StackOverFlowException在WPF中,当从C ++库调用方法方法、StackOverFlowException、WPF

2023-09-04 10:06:58 作者:怪我入戏太深ゝ

我用C ++在WPF库。这是SDK的磁条读/写。当我打电话的是在WPF方法之一,我在10秒后收到StackOverFlowException。所谓从按钮单击事件的方法。

I use C++ library in WPF. It's SDK for Magnetic Stripe Reader/Writer. When I call one of it's methods in WPF, I receive StackOverFlowException after 10 seconds. Method called from button click event.

[DllImport("MSR_API.dll")]
static extern bool MSR_InitComm(string portname, UInt32 baud);

此方法连接到磁条读取器设备。首先,我测试了在Windows此方法窗体应用程序,一切是伟大的。但是,当我开始写这个库WPF应用程序,我收到StackOverFlowException每次。什么可能是这个功能?

This method connects to Magnetic Stripe Reader device. First I tested this method on Windows Forms application, and everything was great. But when I started to write WPF app with this library, I receive StackOverFlowException everytime. What could be the reason of this "feature"?

推荐答案

获取[的DllImport]声明错的是一个标准的原因。的CallingConvention属性是非常重要的。犯错导致堆栈拿到不平衡,最终导致所以如果你把它往往不够。这里有一个MDA的是,要确保你没有关闭PinvokeStackImbalance。使用调试+的Windows +寄存器是另一种方式来诊断它,ESP寄存器值必须是相同的前,后调用。

Getting the [DllImport] declaration wrong is a standard cause. The CallingConvention property is very important. Getting it wrong causes the stack to get imbalanced, ultimately causing SO if you call it often enough. There's an MDA for that, make sure you didn't turn off PinvokeStackImbalance. Using Debug + Windows + Registers is another way to diagnose it, the ESP register value must be the same before and after the call.

CallingConvention.Cdecl通常需要C或C ++ code除非code的明确写入与__stdcall关键字。

CallingConvention.Cdecl is often required for C or C++ code unless that code was explicitly written with the __stdcall keyword.

好了,Embarcadero的环节还有另外一个原因为异常。 Borland公司库启用传统的FPU异常。这是与.NET code严重不符。尤其是WPF,因为它大量使用了双打控制大小和位置。一个FPU堆栈溢出是一个有点奇怪,你更通常有麻烦NaN值。

Okay, the Embarcadero link suggests another reason for the exception. Borland libraries traditionally enabled FPU exceptions. That's grossly incompatible with .NET code. Especially WPF because it heavily uses doubles for control sizes and positions. An FPU stack overflow is a bit odd, you more typically have trouble with NaN values.

如果你没有库的源$ C ​​$ C,那么你没有太多吸引力的选择来解决这个问题。有一件事你可以尝试是引发和图书馆的第一个电话后捕获异常。在.NET异常处理管道复位FPU控制字。像这样的:

If you don't have the source code of the library then you don't have many attractive options to fix the problem. One thing you can try is to throw and catch an exception after the first call to the library. The .NET exception handling plumbing resets the FPU control word. Like this:

bool ok = MSR_InitComm("COM1", 9600);
try {
    throw new Exception("Fpu reset intended");
}
catch (Exception) {
}