我在WPF中使用C++库.它是磁条读取器/写入器的SDK.当我在WPF中调用其中一个方法时,我在10秒后收到StackOverFlowException.从按钮点击事件调用的方法.
[DllImport("MSR_API.dll")]
static extern bool MSR_InitComm(string portname, UInt32 baud);
Run Code Online (Sandbox Code Playgroud)
此方法连接到磁条读取器设备.首先,我在Windows Forms应用程序上测试了这个方法,一切都很棒.但是当我开始用这个库编写WPF应用程序时,我每次都会收到StackOverFlowException.这个"功能"的原因是什么?
使[DllImport]声明错误是一个标准原因.CallingConvention属性非常重要.错误导致堆栈失去平衡,如果你经常调用它,最终会导致错误.有一个MDA,确保你没有关闭PinvokeStackImbalance.使用Debug + Windows + Registers是诊断它的另一种方法,ESP寄存器值在调用之前和之后必须相同.
C或C++代码通常需要CallingConvention.Cdecl,除非该代码是使用__stdcall关键字显式编写的.
好的,Embarcadero链接提出了例外的另一个原因.Borland库传统上启用了FPU异常.这与.NET代码完全不兼容.尤其是WPF,因为它大量使用双打来控制大小和位置.FPU堆栈溢出有点奇怪,您通常会遇到NaN值问题.
如果您没有库的源代码,那么您没有很多有吸引力的选项来解决问题.您可以尝试的一件事是在第一次调用库之后抛出并捕获异常..NET异常处理管道重置FPU控制字.像这样:
bool ok = MSR_InitComm("COM1", 9600);
try {
throw new Exception("Fpu reset intended");
}
catch (Exception) {
}
Run Code Online (Sandbox Code Playgroud)