c#使用dllimport调用c++生成的dll库文件报错。
报错信息为:
对 PInvoke 函数“xxx”的调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配。
解决方法:
点击C++项目属性,来到配置属性下面的C/C++,点击高级,在右边的“调用约定”里,选择 __stdcall (/Gz)
以下是产生上述问题的原因(_stdcall与_cdecl两者之间的区别):
WINDOWS的函数调用时需要用到栈(STACK,一种先入后出的存储结构)。当函数调用完成后,栈需要清除,这里就是问题的关键,如何清除??
如果我们的函数使用了_cdecl,那么栈的清除工作是由调用者,用COM的术语来讲就是客户来完成的。这样带来了一个棘手的问题,不同的编译器产生栈的方式不尽相同,那么调用者能否正常的完成清除工作呢?答案是不能。
如果使用__stdcall,上面的问题就解决了,函数自己解决清除工作。所以,在跨(开发)平台的调用中,我们都使用__stdcall(虽然有时是以WINAPI的样子出现)。
阅读(4341) | 评论(0) | 转发(0) |