티스토리 뷰



C#으로 응용 프로그램을 제작하는 과정에서 모든 라이브러리가 C# 닷넷 라이브러리로 제작되어 있다면 사용도 디버깅도 편리한 장점이 있지만 현실은 아직 언어들 예를들어 C++이나 기타 언어로 만들어진 DLL을 사용해야 되는 경우가 종종 발생합니다.

PInvokeStackImbalance' 관리 디버깅 도우미가 '.........vshost.exe'에서 문제를 발견했습니다.

추가 정보: PInvoke 함수 '..........::SMSUnitSend'에 대한 호출 결과 스택이 불안정하게 되었습니다. 관리되는 PInvoke 시그니처와 관리되지 않는 대상 시그니처가 일치하지 않기 때문인 것 같습니다. 호출 규칙 및 PInvoke 시그니처의 매개 변수와 관리되지 않는 대상 시그니처가 일치하는지 확인하십시오.

예전에는 별 문제 없이 사용했던 코드인데 기준 닷넷 버전을 4.0으로 올리고 나니 위의 그림과 같은 오류가 발생 했습니다.

extern "C" __declspec(dllimport) int SMSUnitSend(char *UserCode, char *UserName,  
         char *DeptCode, char *DeptName, char *ReqPhone1, char *ReqPhone2, char *ReqPhone3,  
         char *CallName, char *CallPhone1, char *CallPhone2, char *CallPhone3,  
         char *CallMessage, char *RDate, char *RTime, long dwCallNo); 

DLL에 있는 함수들에 대상 함수의 원형은 위의 코드와 같습니다. 파라미터로 문자열의 포인터들과 long형의 값을 받는 함수로 C#에서 해당 함수를 호출하려면 "using System.Runtime.InteropServices;"를 추가해 주고 다음과 같은 선언 작업도 필요합니다.

[DllImport("AppSMSCall.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int SMSUnitSend(string UserCode, string UserName, string DeptCode, 
    string DeptName, string ReqPhone1, string ReqPhone2, string ReqPhone3,
    string CallName, string CallPhone1, string CallPhone2, string CallPhone3, 
    string CallMessage, string RDate, string RTime, long dwCallNo);

char * 포인터 대신에 string으로 변환한것 빼고는 함수 원형과 크게 다르지 않습니다. 오류가 발생할 원인은 "[DllImport("AppSMSCall.dll")]" 부분에 있었습니다. 이전 코드에는 CallingConvention을 지정하지 않았던 것입니다. C++ 코드의 경우 Cdecl을 사용하고 델파이등으로 만들어진 DLL은 StdCall로 지정하면 됩니다.


댓글
댓글쓰기 폼