c++이나 c언어로 개발된 DLL을 C#에서 이용해야 할 경우
C에 정의된 함수들을 DllImport를 통해 먼저 C#에서 선언을 해줘야 합니다.
다들 이미 아시겠지만.
일반적인 함수는 다들 아실거고 콜백 함수 부분만 설명을 드리겠습니다.
* C, C++로 개발된 DLL에 정의된 콜백함수 원형 (두번째 파라미터에서 문자열(한글)이 넘어옴)
typedef char*(*DLLCALLBACK)(char*, char*, int);
void __stdcall SetCallBack(void* a_pHandle, DLLCALLBACK a_pCallBack);
그리고 DLL 함수와 콜백을 C#에서 사용하기 위한 선언부
public delegate void DLLCALLBACK(String Code, IntPtr Data, int Datalen); [DllImport("callback.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)] public static extern void SetCallBack(IntPtr pCallback, DLLCALLBACK pCallbackFunc); public DLLCALLBACK callback; //생성자든 어디든 적당한데서 콜백 생성 callback = new DLLCALLBACK(CallbackFunc);
위 소스를 보면 delegate 정의할 때, 첫번째 파라미터는 스트링
두번째 파라미터는 IntPtr로 서로 다르게 선언했습니다.
DLL에서는 둘다 char* 이지만 C#에서 받을 때, 한글을 받아야 하는 부분은 IntPtr로 선언해
포인터로 접근을 하기 위해서 그렇게 선언한겁니다.
C언어나 씨뿔뿔로 개발된 DLL에서 넘겨주는 콜백 파라미터를
C#에서 String으로 받아버리면 한글 인코딩이 안됩니다.
왜냐면 C#이 DLL에서 받는 시점에 문자열로 인식하게되어
한글이 깨진채로 인식이 되고,
이때는 아무리 Encoding 클래스를 이용해 UTF-8이든 EUC-KR이든
변환해봐야 변환이 안되는거죠. 저도 이것 때메 이틀을 해메서 지금 이 글을 쓰고 있는겁니다.
저는 참 착합니다. 그쵸?
그럼 C#에서 포인터로 받아 버리면, 접근은 어떻게 하느냐??
public static void CallbackFunc(String Code, IntPtr Data, int Datalen) { String strResult = ""; byte[] RecvBytes = new byte[Datalen]; Marshal.Copy(Data, RecvBytes, 0, Datalen); String Msg3 = Encoding.GetEncoding("UTF-8").GetString(RecvBytes); }
댓글