我在一些我已经使用了很长时间的东西上得到了这个奇怪的错误。这可能是Visual Studio2010中的一个新事物,但我不确定。
我正在尝试从C#调用一个用C++编写的未修改的函数。
从我在互联网上读到的和错误消息本身来看,这与我的C#文件中的签名与C++中的签名不同有关,但我真的看不到它。
首先,下面是我未修改过的函数:
TEngine GCreateEngine(int width,int height,int depth,int deviceType);下面是我在C#中的函数:
[DllImport("Engine.dll", EntryPoint = "GCreateEngine", CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr CreateEngine(int width,int height,int depth,int device);当我调试到C++中时,我看到的所有参数都很好,因此我只能认为这与从TEngine (这是一个指向名为CEngine的类的指针)到IntPtr的转换有关。我以前在VS2008中用过这个,没有问题。
发布于 2010-05-31 15:23:30
也许问题出在调用约定上。您确定非托管函数被编译为stdcall而不是其他函数(我猜是fastcall )?
发布于 2011-02-09 01:53:26
我有一个_cdecl c++动态链接库,我在Visual Studio2008中毫不费力地调用了它,然后Visual Studio2010中相同的代码就不能工作了。我得到了同样的PInvoke ..。也不平衡堆栈错误。
我的解决方案是在DllImport(...)中指定调用约定属性:来自:
[DllImport(CudaLibDir)] 至:
[DllImport(CudaLibDir, CallingConvention = CallingConvention.Cdecl)]我猜他们在.NET 3.5和.NET 4.0之间改变了DLLImport的默认调用约定?
发布于 2011-07-21 04:37:53
也可能是在.NET框架版本3.5中,默认情况下禁用了pInvokeStackImbalance MDA。低于4.0 (或者可能是VS2010)的版本是enabled by default。
是的。从技术上讲,代码总是错误的,框架的以前版本会默默地纠正它。
引用.NET Framework 4 Migration Issues document:“为了提高与非托管代码的互操作性,平台调用中不正确的调用约定现在会导致应用程序失败。在以前的版本中,封送处理层在堆栈上解决了这些错误……如果您有无法更新的二进制文件,您可以在应用程序的配置文件中包含[NetFx40\_PInvokeStackResilience](http://msdn.microsoft.com/en-us/library/ff361650%28v=vs.100%29.aspx)元素,以便能够像在早期版本中那样在堆栈上解决调用错误。但是,这可能会影响应用程序的性能。”
解决此问题的一种简单方法是指定调用约定,并确保它与DLL中的约定相同。__declspec(dllexport)应该产生一种cdecl格式。
[DllImport("foo.dll", CallingConvention = CallingConvention.Cdecl)]https://stackoverflow.com/questions/2941960
复制相似问题