C#-调用PInvoke函数'[...]'使s不平衡

我在已经使用了一段时间的某些东西上遇到了这个奇怪的错误。 这可能是Visual Studio 2010中的新事物,但我不确定。
我正在尝试从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中使用过它没有问题。

Sanctus2099 asked 2020-06-29T21:50:37Z
5个解决方案
86 votes

我有一个_cdecl c ++ dll,我从Visual Studio 2008毫无问题地调用了它,然后Visual Studio 2010中的相同代码无法正常工作。 我得到了相同的PInvoke ...也平衡了堆栈错误。

我的解决方案是在DllImport(...)属性中指定调用约定:从:

[DllImport(CudaLibDir)] 

至:

[DllImport(CudaLibDir, CallingConvention = CallingConvention.Cdecl)]

我猜他们改变了.NET 3.5和.NET 4.0之间DLLImport的默认调用约定吗?

Scott Morken answered 2020-06-29T21:51:25Z
49 votes

也可能是在.NET Framework 3.5版中,默认情况下禁用了pInvokeStackImbalance MDA。 在4.0(或VS2010)以下,默认情况下启用。

是。 从技术上讲,代码始终是错误的,并且以前的版本 框架默默地纠正了它。

引用.NET Framework 4迁移问题文档:“改进 与非托管代码的互操作性,调用不正确 平台调用中的约定现在会导致应用程序失败。 在 在以前的版本中,封送处理层解决了这些错误, 堆栈...如果您有无法更新的二进制文件,则可以包括 应用程序的配置文件中的<NetFx40_PInvokeStackResilience>元素以启用调用 与早期版本一样,需要解决的错误。 然而, 这可能会影响您的应用程序的性能。”

解决此问题的一种简单方法是指定调用约定,并确保它与DLL中的相同。 __declspec(dllexport)应该产生cdecl格式。

[DllImport("foo.dll", CallingConvention = CallingConvention.Cdecl)]
Keith Vinson answered 2020-06-29T21:51:59Z
22 votes

也许问题出在调用约定上。 您确定非托管函数被编译为stdcall而不是其他东西(我想是fastcall)吗?

PeterK answered 2020-06-29T21:50:51Z
5 votes

如果您的DLL的名称为MyDLL.dll,并且您要在Dll中使用函数MyFunction,请使用以下代码

[DllImport("MyDLL.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
public static extern void MyFunction();

这对我有用。

user3610819 answered 2020-06-29T21:52:23Z
2 votes

以我的情况(使用Intel Fortran 2011 XE编译的VB 2010和DLL),当我的应用程序以.NET Framework 4为目标时,就会出现问题。如果将目标框架更改为3.5版,则一切正常。因此,我想原因是.Net Framework 4中引入了一些原因,但目前我不知道哪个

更新:通过重新编译Fortran DLL并显式指定STDCALL作为DLL中导出名称的调用约定来解决了该问题。

southern_snowman answered 2020-06-29T21:52:49Z
translate from https://stackoverflow.com:/questions/2941960/a-call-to-pinvoke-function-has-unbalanced-the-stack