C# NetFx40\u Pinvokestack似乎不起作用

C# NetFx40\u Pinvokestack似乎不起作用,c#,debugging,.net-4.0,pinvoke,app-config,C#,Debugging,.net 4.0,Pinvoke,App Config,我有一个库,我正试图与C#中的Dot Net 4应用程序一起使用。这是一个binaray运行时,因此我无法访问库源代码。我发现了错误 调用PInvoke函数“XXXXXXXXXX.WinAPI::GetDCEx”失败 使堆栈不平衡。这可能是因为管理的PInvoke 签名与非托管目标签名不匹配。检查一下 PInvoke签名匹配的调用约定和参数 目标非托管签名 如果我禁用PinVokeStacks,应用程序将运行,因为调试器不再抛出它。虽然这解决了应用程序未运行的问题,但显然存在一个问题 我最近读到

我有一个库,我正试图与C#中的Dot Net 4应用程序一起使用。这是一个binaray运行时,因此我无法访问库源代码。我发现了错误

调用PInvoke函数“XXXXXXXXXX.WinAPI::GetDCEx”失败 使堆栈不平衡。这可能是因为管理的PInvoke 签名与非托管目标签名不匹配。检查一下 PInvoke签名匹配的调用约定和参数 目标非托管签名

如果我禁用PinVokeStacks,应用程序将运行,因为调试器不再抛出它。虽然这解决了应用程序未运行的问题,但显然存在一个问题

我最近读到了关于NetFx40_Pinvokestack的文章,这是一个可以放在app.config中的元素,它告诉运行时使用封送层来检测和修复不正确的平台调用声明(如以前的.Net版本)


.....
问题是这似乎对调试器没有任何作用,调试器仍然调用错误

我的问题是,我是否仍然必须禁用PinvokesTack

我如何判断NetFx40_PinvokeStackResility已经工作,封送层正在完成它的工作

PS我正在使用Visual Studio 2010 Express


PPS我已写信给库的所有者,提出了修改其DllImports等的可能解决方案。尽管封送层应解决此问题,但可能会降低性能。再加上它的混乱和不理想。然而,在此期间,我仍然需要一个解决方案,直到库得到更新。

不平衡的堆栈是一种令人讨厌的运行时问题。在调试构建中,您可能会忽略它,因为方法设置和分解堆栈帧的方式可能会隐藏错误堆栈指针值的问题。堆栈指针在方法出口处恢复。在发布版本中,这种运气的几率会降低。特别是由于方法内联,它删除了堆栈设置/拆卸代码

NET4中需要NetFx40_PinvokeStackResility元素,因为它们优化了pinvoke封送器。这会破坏早期版本中的错误代码,添加元素会禁用该优化。它对整个计划具有全球性影响。这并不是要禁用MDA,这将隐藏一个非常真实的问题。它只是为It员工提供了一种解决兼容性问题的方法

您可以通过将pinvoke调用放入一个单独的方法来降低风险,该方法只进行调用,而不执行任何操作。您必须用[MethodImpl(MethodImplOptions.NoInLine)]来修饰它,这样优化器就不能内联它了。该helper方法不能有任何out或ref参数,并且不能返回结构类型的值,并且在调用后不应该有任何其他代码


很明显,您需要投入尽可能多的时间来真正解决这个问题。有人可以帮你做原始的C声明,但是我们不能帮你找到他。不发布pinvoke声明也消除了有人猜测它的可能性。

不平衡的堆栈是一种令人讨厌的运行时问题。在调试构建中,您可能会忽略它,因为方法设置和分解堆栈帧的方式可能会隐藏错误堆栈指针值的问题。堆栈指针在方法出口处恢复。在发布版本中,这种运气的几率会降低。特别是由于方法内联,它删除了堆栈设置/拆卸代码

NET4中需要NetFx40_PinvokeStackResility元素,因为它们优化了pinvoke封送器。这会破坏早期版本中的错误代码,添加元素会禁用该优化。它对整个计划具有全球性影响。这并不是要禁用MDA,这将隐藏一个非常真实的问题。它只是为It员工提供了一种解决兼容性问题的方法

您可以通过将pinvoke调用放入一个单独的方法来降低风险,该方法只进行调用,而不执行任何操作。您必须用[MethodImpl(MethodImplOptions.NoInLine)]来修饰它,这样优化器就不能内联它了。该helper方法不能有任何out或ref参数,并且不能返回结构类型的值,并且在调用后不应该有任何其他代码


很明显,您需要投入尽可能多的时间来真正解决这个问题。有人可以帮你做原始的C声明,但是我们不能帮你找到他。不发布pinvoke声明也消除了有人猜测的可能性。

非常感谢您的回答。不幸的是,这是一个封闭源代码库,所以我不能自己修复它,我知道它的DLL中有问题。然而,我已经通知了业主,但同时要求临时解决方案。我还有一个问题,这个库是一个UI库,我希望使用的功能是一个扩展的表单类,它也恰好用作我的入口点,并用于应用程序中的大多数表单。。。。。。。。。。。。因此,整个应用程序都会受到影响。我想我可以同时使用NetFx40_PinvokestackResility,然后在修复库时将其删除,或者在可能的情况下重新投资于新库。我假设pinvoke marshaller可以让我度过这段时间,但要付出性能成本。你觉得怎么样?非常感谢你的回答。不幸的是,这是一个封闭源代码库,所以我不能自己修复它,我知道它的DLL中有问题。然而,我已经通知了业主,但同时要求临时解决方案。我还有一个问题,这个库是一个UI库,我希望使用的功能是一个扩展的表单类,它碰巧也被用作我的入口点,并在大多数表单上使用
<configuration>
  <runtime>
    <NetFx40_PInvokeStackResilience enabled="1" />
  </runtime>
  .....
</configuration>