C# PinvokesTackc调用非托管C++;功能 切换到VS2010后,托管调试助手正在从一个C应用程序调用到非托管C++函数中显示一个不平衡堆栈的错误。
通常的嫌疑犯似乎不是问题的根源。还有什么我需要检查的吗?VS2008构建的C++ DLL和C语言应用程序从来没有问题,没有奇怪或神秘的bug -是的,我知道这并不重要。 以下是已检查的内容:C# PinvokesTackc调用非托管C++;功能 切换到VS2010后,托管调试助手正在从一个C应用程序调用到非托管C++函数中显示一个不平衡堆栈的错误。,c#,c++,visual-studio-2010,pinvoke,dllimport,C#,C++,Visual Studio 2010,Pinvoke,Dllimport,通常的嫌疑犯似乎不是问题的根源。还有什么我需要检查的吗?VS2008构建的C++ DLL和C语言应用程序从来没有问题,没有奇怪或神秘的bug -是的,我知道这并不重要。 以下是已检查的内容: dll名称是正确的 入口点名称正确,并已通过Dependes.exe验证-代码必须使用损坏的名称,确实如此 调用约定是正确的 尺寸和类型似乎都是正确的 字符集是正确的 忽略错误后似乎没有任何问题,在调试器外部运行时也没有问题 C#: C++: 以下是错误: 托管调试助手 “PinVokeStackDis
- dll名称是正确的
- 入口点名称正确,并已通过Dependes.exe验证-代码必须使用损坏的名称,确实如此
- 调用约定是正确的
- 尺寸和类型似乎都是正确的
- 字符集是正确的
- 忽略错误后似乎没有任何问题,在调试器外部运行时也没有问题
在结构的C++声明中不指定填充,但不在C++版本中指定。由于混合的字符数组并非都是4的倍数,而是奇数个2字节的短字符,因此编译器可能会在结构中插入填充并添加结尾 尝试将结构包装在
#pragma pack
中,以确保没有填充
#pragma pack(push)
#pragma pack(1)
// The struct
#pragma pack(pop)
在C++中指定STDCULL,而不是C++,这里的错配会导致函数和调用方从堆栈中弹出参数。p> 另一方面,有一个编译器开关将打开stdcall作为默认调用约定,(-Gz)您正在使用它吗
或者在你的C中试试这个++short __stdcall SuperSpecialOpenFileFunc(SuperSpecialStruct * stuff);
与描述的非托管C++应用程序有同样的问题,这些程序已经运行了多年。当我们升级到VS2010时,我们开始收到PinvokesTack消息
<>将C++中的“Cdecl”调用添加到“C++签名”中,使问题消失。如上面提到的,在C++函数上可以使用<代码>“ysSTDele>”/>代码>或在<代码> > dLimPult > < < /P> > P> >。
[DllImport("mydll.dll", CallingConvention = CallingConvention.Cdecl)]
它工作得很好。是的,无论如何都应该放上“pragma包”,但我认为也不是这样。你不能看到它,但是C++应用程序将它的结构的大小,用Malthal.Sizeof计算到C++ DLL,C++的DLL验证了由SIEZOFF()计算的C++结构大小与传入的值相同。是的,我也得到了这个,我不知道为什么。你可能会认为,如果调用约定被打乱了,它会完全破坏堆栈,并且无法工作。我打的每一个电话都是这么说的。同样的问题,不知道为什么。程序仍然有效。但是,对于我来说,将C++函数改为y-STDCALL修复了问题。从.NETFramework 4开始,一个简化的互操作封送处理体系结构为从托管代码到非托管代码的转换提供了显著的性能改进。在早期版本的.NET Framework中,封送处理层在32位平台上检测到不正确的平台调用声明,并自动修复堆栈。
short __stdcall SuperSpecialOpenFileFunc(SuperSpecialStruct * stuff);
[DllImport("mydll.dll", CallingConvention = CallingConvention.Cdecl)]