pinvokestackimbalance - 如何修复此问题或将其关闭?

mmr*_*mmr 73 c# c++ pinvoke visual-studio-2010 visual-studio

我刚从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);
Run Code Online (Sandbox Code Playgroud)

这是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);

}
Run Code Online (Sandbox Code Playgroud)

vs2010和vs2008之间有什么不同会导致这些异常被抛出?我应该在DllImport指令中添加一组不同的参数吗?

Ste*_*ary 138

首先,要了解代码是错误的(并且始终存在)."pInvokeStackImbalance"本身不是一个例外,而是一个托管调试助手.它默认在VS2008中关闭,但是很多人没有打开它,所以默认情况下它在VS2010中启用.MDA不在发布模式下运行,因此如果您为发布版本构建它将不会触发.

在您的情况下,调用约定是不正确的.DllImport默认为CallingConvention.WinApi,与CallingConvention.StdCallx86桌面代码相同.它应该是CallingConvention.Cdecl.

这可以通过编辑以下行[DllImport("ImageOperations.dll")]来完成:

[DllImport("ImageOperations.dll", CallingConvention = CallingConvention.Cdecl)]
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅此MSDN参考

  • 很可能.这种特殊类型的堆栈不平衡实际上有点普遍; 它不会立即引起任何错误,但会慢慢消耗线程的堆栈.最终,"坏事"将会发生.CLR通常*能够引发一个`StackOverflowException`,但是当堆栈已满时,`using`,`catch`和`finally`块会使事情变得复杂.因此,从.NET 2.0开始,`StackOverflowException`将终止进程. (4认同)

小智 40

要关闭它:

  1. CTRL + ALT + E.
  2. 在"托管调试助手"下,取消选中PInvokeStackImbalance.

  • 绝不,*绝不*,**绝不**向信使开枪。堆栈不平衡迟早会吃掉你的肝脏和蚕豆。 (4认同)

Vij*_*oje 8

更好地解决这个问题在这里并不困难我提到了一些方法,它可能与我上面提到的一些朋友一样.我正在使用PCSC一个智能卡应用程序我花了大约一个星期,生气了很多变化终于得到了解决方案.

对于我与VS2010安装的PInvoke Extension的工作,你可以在这里下载http://www.red-gate.com/products/dotnet-development/pinvoke/

下载并安装它,关闭visual studio并再次打开,您可以在菜单栏找到扩展名. 在此输入图像描述

如果错误是由于签名不匹配,您只需单击PInvoke.net>插入PInvoke签名

新窗口将如下所示 在此输入图像描述

输入dll的名称并单击搜索,您可以在搜索结果窗口中看到该dll的所有功能,单击该功能,您将获得该特定功能的签名.

使用该签名,您需要根据签名修改您的程序,主要是数据类型.

这解决了我的问题,你可能有不同的问题,如callConvention或导入DLL时需要指定的其他属性.

快乐的编码很好!