pinvokestackimbalance——我该如何解决这个问题或将其关闭?
我刚刚从vs2008切换到vs2010。完全相同的解决方案,只不过现在对 C++ dll 的每次调用都会产生“pinvokestackimbalance”异常。
此异常在 2008 年不会被触发。我可以完全访问 C++ dll 和调用应用程序。 pinvoke看起来没有任何问题,但是这个问题使得调试其他问题变得不可能; IDE 不断停下来告诉我这些事情。
例如,这是 C# 签名:
[DllImport("ImageOperations.dll")]
static extern void FasterFunction(
[MarshalAs(UnmanagedType.LPArray)]ushort[] inImage, //IntPtr inImage,
[MarshalAs(UnmanagedType.LPArray)]byte[] outImage, //IntPtr outImage,
int inTotalSize, int inWindow, int inLevel);
这是 C++ 端的样子:
#ifdef OPERATIONS_EXPORTS
#define OPERATIONS_API __declspec(dllexport)
#else
#define OPERATIONS_API __declspec(dllimport)
#endif
extern "C" {
OPERATIONS_API void __cdecl FasterFunction(unsigned short* inArray,
unsigned char* outRemappedImage,
int inTotalSize,
int inWindow, int inLevel);
}
vs2010 和 vs2008 之间有什么不同会导致抛出这些异常?我应该向 DllImport 指令添加一组不同的参数吗?
I just switched to vs2010 from vs2008. Exact same solution, except now every single call to a C++ dll yields a 'pinvokestackimbalance' exception.
This exception does not get fired in 2008. I have complete access to the C++ dll and to the calling application. There does not appear to be any problem with the pinvoke, but this problem is making debugging other problems impossible; the IDE is stopping constantly to tell me about these things.
For instance, here's the C# signature:
[DllImport("ImageOperations.dll")]
static extern void FasterFunction(
[MarshalAs(UnmanagedType.LPArray)]ushort[] inImage, //IntPtr inImage,
[MarshalAs(UnmanagedType.LPArray)]byte[] outImage, //IntPtr outImage,
int inTotalSize, int inWindow, int inLevel);
Here's what it looks like on the C++ side:
#ifdef OPERATIONS_EXPORTS
#define OPERATIONS_API __declspec(dllexport)
#else
#define OPERATIONS_API __declspec(dllimport)
#endif
extern "C" {
OPERATIONS_API void __cdecl FasterFunction(unsigned short* inArray,
unsigned char* outRemappedImage,
int inTotalSize,
int inWindow, int inLevel);
}
What's different between vs2010 and vs2008 that would cause these exceptions to get thrown? Should I be adding a different set of parameters to the DllImport directive?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
首先,要明白代码是错误的(而且一直都是错误的)。 “pInvokeStackImbalance”本身并不是一个例外,而是一个托管调试助手。在VS2008中默认是关闭的,但是很多人并没有打开它,所以在VS2010中默认是打开的。 MDA 不在发布模式下运行,因此如果您构建发布版本,它不会触发。
在您的情况下,调用约定不正确。
DllImport
默认为CallingConvention.WinApi
,它与 x86 桌面代码的CallingConvention.StdCall
相同。它应该是CallingConvention.Cdecl
。这可以通过将
[DllImport("ImageOperations.dll")]
行编辑为:有关详细信息,请参阅 此 MSDN 参考
First, understand that the code is wrong (and always has been). The "pInvokeStackImbalance" is not an exception per se, but a managed debugging assistant. It was off by default in VS2008, but a lot of people did not turn it on, so it's on by default in VS2010. The MDA does not run in Release mode, so it won't trigger if you build for release.
In your case, the calling convention is incorrect.
DllImport
defaults toCallingConvention.WinApi
, which is identical toCallingConvention.StdCall
for x86 desktop code. It should beCallingConvention.Cdecl
.This can be done by editing the line
[DllImport("ImageOperations.dll")]
to be:For more information, see this MSDN reference
要将其关闭:
To turn it off:
更好的解决这个问题其实并不难,这里我提一些方法,可能和上面一些朋友说的一样。我正在与 PCSC 合作开发一个智能卡应用程序,我花了大约一周的时间,做了很多更改终于得到了解决方案,这让我很生气。
对我来说,它与我为 VS2010 安装的 PInvoke 扩展一起使用,您可以在这里下载它 http ://www.red-gate.com/products/dotnet-development/pinvoke/
下载并安装,关闭Visual Studio并再次打开即可在菜单栏找到扩展程序。
如果错误是由于签名不匹配,您只需单击 PInvoke.net>;插入 PInvoke 签名
新窗口将如下所示
输入dll的名称,点击搜索即可在搜索中看到该dll的所有功能在结果窗口中,单击该函数,您将获得该特定函数的签名。
使用该签名,您需要根据该签名(主要是数据类型)修改您的程序。
这解决了我的问题,您可能会遇到不同的问题,例如调用约定或导入 dll 时需要指定的其他属性。
快乐编码 一切都好!
Better to solve this issue its not much difficult here I am mentioning some of the methods, it may same as some of my friends mentioned above. I am working with PCSC a Smartcard application I spend around one week, get pissed off did lot of changes finally got the solutions.
For me its work with PInvoke Extension which I installed for VS2010 you can download it here http://www.red-gate.com/products/dotnet-development/pinvoke/
Download it and install it, Close visual studio and open again you can find extension at Menu Bar.
If the error is because of signature not matching you just click on PInvoke.net> Insert PInvoke Signatures
The new window will appear like below
Enter the name of the dll and click on search you can see the all the functions of that dll in search result window, Click on the function you will get a signature for that particular Function.
Use that signature and you need to modify your programs according to that Signature, Mostly the data Type.
This solve my problem you might have different problem like callingConvention or additional attributes need to specify while importing dll.
Happy Coding Be well!
我在使用VS2010的时候也遇到了这个问题。
它是什么:
Visual Studio 默认为“任何 CPU”使用 64 位代码。
当调用外部 Dll 时,变量(例如字符串)的指针现在变为 64 位,而所有可靠且可信的 Dll 都使用 32 位指针。
不要认为您的 Dll 有任何问题,事实并非如此。
更改 VS 设置以生成如下所示的 X86 代码(C# 的 Express 版本)
我还注意到,尽管计算机的性能每 12 个月就会增加一倍,但我目前拥有 1GB RAM 的计算机似乎并不比我的第一台 4Meg 的 486 快。
不要担心使用 64 位代码,它不会更快或更好,因为它是建立在一个巨大的、笨重的、臃肿的面向对象塔之上的。
I got this problem also when using VS2010.
What it is:
Visual Studio defaults to 64 bit code for 'any CPU'.
The pointers to variables (eg. strings) now become 64 bit when calling your external Dlls, where as all your reliable and trusted Dlls use 32 bit pointers.
Don't assume there is anything wrong with your Dlls, there isn't.
Change your VS settings to generate X86 code like this (Express versions of C#)
I notice also, that even though computers have doubled in power every 12 months, my current computer with 1gig of RAM, seems no faster than my first 486 with 4 Meg.
Don't worry about using 64 bit code, it's not going to be faster or better because it is built on a huge cumbersome object-orientated tower of bloat.
我尝试使用
CallingConvention
isThisCall
调用 dll,它对我有用。这是我使用 BLOB MS Sql Server 的代码。更多信息请访问:https:/ /msdn.microsoft.com/en-us/library/system.runtime.interopservices.callingconvention(v=vs.110).aspx
I tried to call dll with the
CallingConvention
isThisCall
and it worked for me. Here is my code working with BLOB MS Sql Server.More at: https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.callingconvention(v=vs.110).aspx