pinvokestackimbalance – 如何解决这个问题或closures它?
我刚刚从vs2008切换到vs2010。 完全相同的解决scheme,除了现在每一个C ++ DLL调用产生一个'pinvokestackimbalance'exception。
这个exception在2008年没有被解雇。我可以完全访问C ++ dll和调用应用程序。 似乎没有任何问题,但这个问题正在debugging其他问题不可能; 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有什么不同,会导致这些exception被抛出? 我应该向DllImport指令添加一组不同的参数吗?
首先,明白代码是错误的(而且一直是)。 “pInvokeStackImbalance”本身不是一个例外,而是一个托pipedebugging助手。 它在VS2008默认closures,但很多人没有打开它,所以默认在VS2010中。 MDA不能在Release模式下运行,所以如果您为发布版本构build,它将不会触发。
在你的情况下,调用约定是不正确的。 DllImport
默认为CallingConvention.WinApi
,与x86桌面代码的CallingConvention.StdCall
相同。 它应该是CallingConvention.Cdecl
。
要closures它:
- CTRL + ALT + E
- 在“托pipedebugging助手”下,取消选中PInvokeStackImbalance。
更好的解决这个问题它并不难,在这里我提到一些方法,它可能和我上面提到的一些朋友一样。 我正在与PCSC智能卡应用程序,我花了一个星期左右,生气了很多变化终于得到了解决scheme。
对于我在VS2010中安装的PInvoke Extension的工作,你可以在这里下载http://www.red-gate.com/products/dotnet-development/pinvoke/
下载并安装它,closuresVisual Studio并再次打开,您可以在菜单栏中find扩展名。
如果错误是由于签名不匹配,您只需点击PInvoke.net>插入PInvoke签名
新窗口将显示如下
inputDLL的名称,然后点击search,您可以在search结果窗口中看到该DLL的所有function,单击该function,您将获得该特定function的签名。
使用该签名,您需要根据该签名来修改程序,主要是数据types。
这解决了我的问题,你可能有不同的问题,如调用常规或额外的属性需要指定,同时导入DLL。
快乐编码做得好!
使用VS2010时我也遇到了这个问题。 它是什么:Visual Studio默认为“任何CPU”的64位代码。 当调用外部Dll时,指向variables(例如string)的指针现在变成了64位,因为所有可靠和可信的Dll都使用了32位指针。
不要以为你的Dll有什么问题,没有。
改变你的VS设置,像这样生成X86代码(Express版本的C#)
- 去工具 – >选项。
- 在“选项”对话框的左下angular,选中“显示所有设置”框。
- 在左侧的树形视图中,select“项目和解决scheme”。
- 在右侧的选项中,选中“显示高级构buildconfiguration”框。
- 点击OK。
- 转到生成 – >configurationpipe理器…
- 在项目旁边的“平台”列中,单击combobox并select“”。
- 在“新平台”设置中,select“x86”。
- 点击OK。
- 点击closures。
我还注意到,即使计算机每12个月的功耗翻了一番,我现在的计算机配备了1G内存,似乎没有比我第一次使用4M计算的486还快。 不要担心使用64位代码,因为它是build立在一个庞大的面向对象的庞大的塔之上的,所以不会更快或更好。
我试着打电话给dll CallingConvention
是ThisCall
它为我工作。 这里是我的代码与BLOB MS Sql服务器一起工作。
[DllImport("sqlncli11.dll", SetLastError = true, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.ThisCall)] private static extern SafeFileHandle OpenSqlFilestream( string FilestreamPath, UInt32 DesiredAccess, UInt32 OpenOptions, byte[] FilestreamTransactionContext, UInt32 FilestreamTransactionContextLength, Int64 AllocationSize);
更多信息, 请访问: https : //msdn.microsoft.com/en-us/library/system.runtime.interopservices.callingconvention(v = vs.110).aspx