对 PInvoke 函数“[...]”的调用堆栈不平衡
我在使用了很长一段时间的一些东西上遇到了这个奇怪的错误。这可能是 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中用过这个,没有问题。
I'm getting this weird error on some stuff I've been using for quite a while. It may be a new thing in Visual Studio 2010 but I'm not sure.
I'm trying to call a unamanged function written in C++ from C#.
From what I've read on the internet and the error message itself it's got something to do with the fact that the signature in my C# file is not the same as the one from C++ but I really can't see it.
First of all this is my unamanged function below:
TEngine GCreateEngine(int width,int height,int depth,int deviceType);
And here is my function in C#:
[DllImport("Engine.dll", EntryPoint = "GCreateEngine", CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr CreateEngine(int width,int height,int depth,int device);
When I debug into C++ I see all arguments just fine so thus I can only think it's got something to do with transforming from TEngine (which is a pointer to a class named CEngine) to IntPtr. I've used this before in VS2008 with no problem.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我有一个 _cdecl c++ dll,从 Visual Studio 2008 中调用它没有任何问题,然后 Visual Studio 2010 中的相同代码将无法工作。我得到了相同的 PInvoke ...也使堆栈错误不平衡。
我的解决方案是在 DllImport(...) 属性中指定调用约定:
来自:
至:
我猜他们更改了 .NET 3.5 和 .NET 4.0 之间 DLLImport 的默认调用约定?
I had a _cdecl c++ dll that I called without any trouble from Visual Studio 2008, and then the identical code in Visual Studio 2010 would not work. I got the same PInvoke ... has unbalanced the stack error as well.
The solution for me was to specify the calling convention in the DllImport(...) attribute:
From:
To:
I guess they changed the default calling convention for DLLImport between .NET 3.5 and .NET 4.0?
也可能是在 .NET Framework 版本 3.5 中,默认情况下禁用 pInvokeStackImbalance MDA。在4.0(或者可能是VS2010)下,它是
解决此问题的一个简单方法是指定调用约定并确保它与 DLL 中的相同。
__declspec(dllexport)
应该产生 < em>cdecl 格式。It could also be that in the .NET Framework version 3.5, the pInvokeStackImbalance MDA is disabled by default. Under 4.0 (or maybe VS2010) it is enabled by default.
An easy way to fix this is to specify the calling convention and make sure it is the same as in the DLL. A
__declspec(dllexport)
should yield a cdecl format.也许问题出在调用约定上。您确定非托管函数被编译为 stdcall 而不是其他东西(我猜是 fastcall )?
Maybe the problem lies in the calling convention. Are you sure the unmanaged function was compiled as stdcall and not something else ( i would guess fastcall ) ?
如果您的 DLL 名称为 MyDLL.dll,并且您想在
对我有用的 Dll 中使用函数 MyFunction,请使用以下代码。
Use the following code, if say your DLL has the name MyDLL.dll and you want to use the function MyFunction within the Dll
this worked for me.
就我而言(VB 2010 和使用 Intel Fortran 2011 XE 编译的 DLL),当我的应用程序面向 .NET Framework 4 时,就会出现问题。如果我将目标框架更改为版本 3.5,那么一切都会按预期正常工作。
所以,我猜测原因是 .Net Framework 4 中引入的某些内容,但我目前不知道是哪一个
更新:通过重新编译 Fortran DLL 并显式指定 STDCALL 作为 DLL 中导出名称的调用约定解决了该问题。
In my case (VB 2010 and DLL compiled with Intel Fortran 2011 XE) the problem exists when my application targets .NET Framework 4. If I change targeted framework to version 3.5, then everything works fine as expected.
So, I would guess the reason is something introduced in .Net Framework 4 but I have no idea at the moment which one
Update: The problem was solved by recompiling Fortran DLL and explicitly specifying STDCALL as calling convention for export names in the DLL.