반응형

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