【发布时间】:2011-07-02 18:24:54
【问题描述】:
我们正在将我们的代码库从 BDS2006 迁移到 Rad Studio XE,我们发现了一些非常奇怪的行为:如果我们在从 .Net4.0 中实现的 COM 服务器创建一些对象后进行无效的浮点运算(即除零) ,我们没有得到正常的异常(即 EDivisionByZero),而是 EStackOverflow。
我们设法准备了非常简单的例子:ComErrorExample
有一个 .net 4.0 程序集,带有 com 接口(一个函数返回字符串)和简单的 delphi 应用程序:
var
a, b: Double;
Stored8087CW: Word;
begin
CoInitialize(nil);
try
b := 0;
a := 1 / b;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message, ' (Expected type of exception)');
end;
Stored8087CW := Get8087CW;
Writeln('Code from .NET COM: ', CoExampleOfCOM.Create.DoSomething);
Set8087CW(Stored8087CW); //it's only to show that 8087 control word doesn't change
try
b := 0;
a := 1 / b;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message, ' (Unexpected type of exception! Why stack overflow?)');
end;
Readln;
CoUninitialize;
end.
如您所见,我们将两个除以零 - 第一个在创建 com 对象之前抛出 EDivisionByZero,第二个抛出 EStackOverflow。
我们在 win7 x64 和 winXP x32 上对此进行了测试 - 没有区别。但是当我们将 com 服务器从 .net4.0 切换到 .net3.5 时,一切正常。
问题:我们做错了吗?我们能做点什么来解决这个问题吗?
切换到 .net3.5,或者放弃 Delphi 对我们来说不是一个选择。
更新: 我们之前检查了浮点配置( Set8087CW() ),但没有任何运气。 UPDATE2:我已经扩展了恢复浮点配置的示例。
【问题讨论】:
-
可能是 FPU 堆栈溢出,原因是 .net 或 MS 编译器中的浮点模型发生了一些变化 - 只是猜测。
-
FPU 堆栈溢出类似于 EInvalidOp IIRC
-
遇到类似问题。你找到解决方案了吗?