반응형
1. DLL Import 과정 ex) EMR_Hash라는 API를 임포트
C에서 파라미터 원형은... 원래는 다음과 같다.
unsigned int ~
int ~
char[] ~
int ~
char[] ~
int * ~
이런 타입이 아래와 같이 변형되서 Import 하였다. (문제없음)

[DllImport("LibEMRClient.dll")] 
public extern static int EMR_Hash(
            uint nCtx,                 
            int nHashAlg,           
            Byte[] pucEMRData,
            int nEMRDataLen,           
            Byte[] aucOutHashedData,
            ref int pnOutHashedDataLen
);



2. 함수호출

m_nRet = EMR_Hash(
                m_unContext, m_nSetAlgo,
                btEMRData, btEMRData.Length,               
                btHashedData, ref nHashedDataLen               
);

신경써서 볼것은, 처음 2개의 파라미터는 쌩까고,
뒤에 4개의 파라미터가 모두 할당해서 넘겨주는 변수이다(Out Parameter)
( bt는 Byte[]타입 )


3. 받아온 값(Out parameter) 정리
char[] acHashedData = new char[nHashedDataLen];
acHashedData = Encoding.Default.GetChars(btHashedData,0,nHashedDataLen);
String stHashedData = new String(acHashedData);
IDC_EDIT_EMR_HASHED_DATA.Text = stHashedData;

char[] 배열을 받아온 길이만큼 선언하고,
받아온 Byte[]에서 Char값을 받아서 복사한다.
그 Char값을 토대로 String 값을 선언 및 초기화
에디트박스에 그 String 값을 적용한다.
반응형
Posted by Rainfly
l
반응형
제목 그데로, C#에서 Binary to Hex String 방법

바이너리데이터 (Byte[])를 ... 받아왔던, 갖고있던...
Hex String으로 나타내는 방법이다.

예제 바로 가자.
m_nRet = EMR_Hash(
                m_unContext, m_nSetAlgo,
                btEMRData, btEMRData.Length,               
                btHashedData, ref nHashedDataLen               
);
btHashedData 가 API OutParameter로 바이너리 값 Byte[] 타입이다.


String Result = BitConverter.ToString(btHashedData).Replace("-", string.Empty);
EDIT_BOX.Text = Result;


String 변수값 Result 값을 선언과 동시에 저렇게 초기화하면
EDIT_BOX의 텍스트값에 넣었을 시 Hex String이 출력된다.
반응형
Posted by Rainfly
l
반응형

C#의 hello world 컴파일도 못 해보고 일단 설치부터 하였다 -_-;;
Visual C# 2005 Express....

여튼 본론 바로 넘어가서....
C의 API를 써야만 했고, DLL API 끌어오는 것부터해서...
char*, char[], string, 파라미터주고받는 등의 막막함을 풀었던
API 한개로 예를 들어보겠다.

노란색 칸
 - C DLL의 Export 되는 함수 원형

녹색 칸
 - C#에서 DLL Import할때 파라미터의 바뀌는 부분들

파랑색
 - Import 된 API 호출에 있어서 작업.

참고로 말하면, char[], char*와 같은 것들을 주고 받아야하지만,
unsafe를 쓸일은 발생하지 않았다.

이글을 보시려는 분들의 대다수가 String 과 Char[] 의 주고받는 부분일 것이라고
생각된다.. 아마도.. 현업종사자분이라면 -_-;;...
분명 우린 툴킷라이브러리가 이미 있는데, 고객들이 C#버전의 클라이언트를 요구해서
테스트해보고 지원여부를 가르는 담당자이실 것 같다... =_=;;

파라미터의 자료형이 바뀌는 부분과 그 파라미터로 넣기위해 선언에서부터 컨버트하는 부분을
보고 얻어가셨으면 좋겠다.

int FAR PASCAL EMR_HashSign(
 unsigned int nCtx,
 char* pcSid,
 unsigned char * pucEMRData,
 int nEMRDataLen,
 unsigned char aucOutSignedData[],
 int* pnOutSignedDataLen
);
[DllImport("LibEMRClient.dll")]
        public extern static int EMR_HashSign(
         uint nCtx,
         Byte[] pcSid,
         Byte[] pucEMRData,
         int nEMRDataLen,
         StringBuilder aucOutSignedData,
         ref int pnOutSignedDataLen
);
private void IDC_BUTTON_HASHSIGN_Click(object sender, EventArgs e)
        {
            if (m_unContext == 0x00)
            {
                MessageBox.Show("Error, API초기화하세요", "-ㅅ-");
                return;
            }

            // 이부분이 Text(String)에서 Byte[]로 복사하고, 그러면서 인코딩하는 부분이다.
            Byte[] btId = System.Text.Encoding.Default.GetBytes(IDC_EDIT_ID.Text);
            Byte[] btEMRData = System.Text.Encoding.Default.GetBytes(IDC_EDIT_EMR_DATA.Text);
            StringBuilder sbHashSignedData = new StringBuilder(4096);
            int nHashSignedData = 0;

            m_nRet = EMR_HashSign(
                m_unContext, btId,
                btEMRData, btEMRData.Length,
                sbHashSignedData, ref nHashSignedData
            );

            if (m_nRet != 0)
            {
                int nErrLen = 2048;
                StringBuilder sbErr = new StringBuilder(nErrLen);

                EMR_GetCodeToMsg(m_unContext, m_nRet, sbErr, ref nErrLen);
                MessageBox.Show(sbErr.ToString(), "APITestProgram");
                return;
            }
            else
            {                // ~.Text는 String Type이다.
                IDC_EDIT_EMR_SIGNED_DATA2.Text = sbHashSignedData.ToString();

                MessageBox.Show("EMR_HashSign Success", "APITestProgram");
            }
            Update();
        }




추가적으로 말씀을 드리자면,
char[] 형태로 스트링을 보낼땐,
String ->Byte[]->(인코딩)
하여 Byte[]상태로 넘겼고, 인코딩은 잘 모르겠으나, C#이 기본적으로 UTF8이고, 이걸 유니코드로
변환이 필요하여서란다.
처음엔 char[]로도 가능하였다. 그런데 스트링길이가 길어지더니, 점점 매끄럽지 못하게, 깨짐 현상이
나타났고, 그 때 Byte[]로 바꾸고 인코딩을 하게 되었더니 정상이 되었다.

char[]형태로 스트링을 받아올땐,
char[] -> StringBuilder -> String (StringBuilder.Tostring())
하여 String값으로 받아왔다. 아직도 StringBuilder가 먼지도 모르겠지만 -_-;;

Int*형태로 보낼때에는
int선언 -> 인자값넣을때 ref 붙이기 (물론 선언도 ref int)라고 하면 되었다.


더 알게되고 하면 지금 글을 보완하겠지만, 막힌 것 풀때마다 어딘가 메모를 해야되는 것은
정학하기에 글을 남겨놓았으며, 도움이 되는 사람이 있었으면 좋겠다.


!! 8월 19일 수정 !!
문자열값을 StringBuilder 방법이 아닌
받아온 길이값을 이용해서 Char[]형태로 받아오는 방법 추가


 

반응형
Posted by Rainfly
l
반응형

C/C++ 파일오픈, 파일읽기, fopen, fread
C/C++ 파일오픈, 파일읽기, fopen, fread



 FILE *pFile = fopen(acFileData, "rb");               //바이너리로 읽기 모드

 char cBuffer[2048]={0,};
 int nByteOfRead = 0;
 int nReturn =0;
 

 while (feof(pFile)==false){                                                // 파일끝이 아니면 계속 루프
  nByteOfRead = fread(cBuffer, 1, sizeof(cBuffer), pFile);       //2048크기만큼 읽어서 cBuffer에 저장
  
  if(nByteOfRead < sizeof(cBuffer)){ // read error or final item
   m_nRet = ferror(pFile);
   if(m_nRet != 0){     // read error
    strerror(nReturn);
    return 에러코드;
   }                          // read error가 아니면, 2048크기가 안된 마지막부분을 읽었다는 것이므로 작업수행
           
  }  
    읽은 버퍼(cBuffer)로 어떤 작업 수행
 }


반응형
Posted by Rainfly
l
반응형
C/C++/MFC 파일선택창 띄워서 파일 불러오기, 불러온파일 패쓰 구하기
- 모든파일(*.*)을 예로 잡고


 CString strFileName;
 CFileDialog fDlg(TRUE, NULL, NULL, OFN_READONLY,"ALL Files (*.*)|*.*||");
 
 int iRet = fDlg.DoModal();
 strFileName = fDlg.GetPathName();                    // Path 집어넣기
 if(iRet != IDOK){                                                // File load Fail Check
  AfxMessageBox("파일지정을 취소하셨습니다");   // Message Box
  return;
 }


반응형
Posted by Rainfly
l