我刚从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指令中添加一组不同的参数吗?
首先,要了解代码是错误的(并且一直都是)。“ pInvokeStackImbalance”本身并不是例外,而是托管的调试助手。在VS2008中默认情况下处于关闭状态,但是很多人没有将其打开,因此在VS2010中默认情况下处于打开状态。MDA不在发布模式下运行,因此如果您为发布而构建,则它不会触发。
在您的情况下,调用约定不正确。DllImport默认为CallingConvention.WinApi,与CallingConvention.StdCallx86桌面代码相同。应该是CallingConvention.Cdecl。
DllImport
CallingConvention.WinApi
CallingConvention.StdCall
CallingConvention.Cdecl
可以通过将行编辑[DllImport("ImageOperations.dll")]为:
[DllImport("ImageOperations.dll")]
[DllImport("ImageOperations.dll", CallingConvention = CallingConvention.Cdecl)]
有关更多信息,请参见此MSDN参考。