首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对PInvoke函数'[...]‘的调用已使堆栈不平衡

对PInvoke函数'[...]‘的调用已使堆栈不平衡
EN

Stack Overflow用户
提问于 2010-05-31 15:19:12
回答 5查看 43.9K关注 0票数 48

我在一些我已经使用了很长时间的东西上得到了这个奇怪的错误。这可能是Visual Studio2010中的一个新事物,但我不确定。

我正在尝试从C#调用一个用C++编写的未修改的函数。

从我在互联网上读到的和错误消息本身来看,这与我的C#文件中的签名与C++中的签名不同有关,但我真的看不到它。

首先,下面是我未修改过的函数:

代码语言:javascript
复制
TEngine GCreateEngine(int width,int height,int depth,int deviceType);

下面是我在C#中的函数:

代码语言:javascript
复制
[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中用过这个,没有问题。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-05-31 15:23:30

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

票数 23
EN

Stack Overflow用户

发布于 2011-02-09 01:53:26

我有一个_cdecl c++动态链接库,我在Visual Studio2008中毫不费力地调用了它,然后Visual Studio2010中相同的代码就不能工作了。我得到了同样的PInvoke ..。也不平衡堆栈错误。

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

代码语言:javascript
复制
[DllImport(CudaLibDir)] 

至:

代码语言:javascript
复制
[DllImport(CudaLibDir, CallingConvention = CallingConvention.Cdecl)]

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

票数 90
EN

Stack Overflow用户

发布于 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格式。

代码语言:javascript
复制
[DllImport("foo.dll", CallingConvention = CallingConvention.Cdecl)]
票数 49
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2941960

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档