PInvoke调用导致堆栈不对称 c#调用C++win32非托管dll的问题深度分析

转自:http://www.cnblogs.com/manyou/archive/2012/07/20/2600565.html

问题描述:对 PInvoke 函数“xxFunction()”的调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配

问题解决:1、在c#中函数声明处改一个参数,[DllImport("xx.dll", EntryPoint=“xxFunction”, CallingConvention = CallingConvention.Cdecl)]调用时不变

     2、在c++代码中改对应的c++函数参数从extern“C” _declspec(dllexport) void xxFunction()改成

       extern“C” _declspec(dllexport) void __stdcall xxFunction()

问题分析:

     在c++WIN32程序中有三种calling convention(呼叫约定):__cdecl, __stdcall, __fastcall默认为__cdecl,而c#中默认为CallingConvention =CallingConvention.Winapi,两个平台呼叫约定不一致,所以会出现提示的不匹配错误。

__cdecl为调用函数即C#中清理堆栈中保存的参数。参数的大小不确定时用这个,比如string

 __stdcall对应c#中CallingConvention =CallingConvention.Winapi,它由c++中函数自动清理。

Win32 calling convention(呼叫约定)的三种约定具体分析见http://www.cnblogs.com/super119/archive/2011/04/10/2011304.html

http://www.cnblogs.com/dust/articles/1190641.html

你可能感兴趣的:(Win32)