본문 바로가기
프로그래밍/오류 해결

PInvokeStackImbalance 이(가) 발생했습니다.

by TcTT 2016. 8. 2.
반응형

C# 으로 외부 SDK를 참조가 아닌 DllImport로 사용중 아래와 같은 런타임 에러가 발생했다.

PInvokeStackImbalance () 발생했습니다.



"~~~~'에 대한 호출 결과 스택이 불안정하게 되었습니다

관리되는 PInvoke 시그니처와 관리되지 않는 대상 시그니처가 일치하지 않기 때문인 것 같습니다. 호출 규칙 및 PInvoke 시그니처의 매개 변수와 관리되지 않는 대상 시그니처가 일치하는지 확인하십시오." 


인터넷에서 검색 하니 이 에러가 발생했을 때, 닷넷 프레임 워크 3.5이하 버전으로 대상 프레임 워크를 변경하면 된다는 글이 많다. 닷넷 버전을 다운그레이드하니 런타임 오류는 사라진다. 하지만 권장하는 에러 해결법은 아니다. 정확한 에러 원인은 DLL파일을 Import할 때 함수 호출규약 CallingConventionDLL파일과 동일하게 설정해 주지 않았기 때문이다.


닷넷 4.0부터는 DllImport할 때 CallingConvention을 지정하지 않는 경우 무조건 __stdcall로 간주하고 함수를 가져온다, 이 때문에 dll에 들어 있는 함수와 실제 부르려고 하는 함수간 호출규약이 다르면 이런 에러가 발생한다.

이제 함수를 부를 때 아래와 같이 실제 CallingConvenction을 명기해주면, 정상적으로 런타임 에러 없이 프로그램이 동작한다.


호출 규약이 없는 Dll Import

[DllImport("helpDLL.dll")]

public static extern int Connect(IntPtr hWnd);   //닷넷 4.0이상이면 정상 작동하지 않는다.


호출 규약을 맞춰준 Dll Import

[DllImport("helpDLL.dll", CallingConvention = CallingConvention.Cdecl)]

public static extern int Connect(IntPtr hWnd);  //닷넷 4.0이상이여도 정상 작동 가능.



[DllImport("helpDLL.dll", CallingConvention = CallingConvention.Cdecl)] 을 사용했음에도 불구하고 동일한 오류가 발생한다면


CallingConvention.StdCall 등 다양하게 사용해보길..

반응형