我们正在将代码库从 BDS2006 迁移到 Rad Studio XE,我们发现了一些非常奇怪的行为:如果我们在从 .Net4.0 中实现的 COM 服务器创建一些对象后进行无效的浮点运算(即除以零),我们不会没有得到正常异常(即 EDivisionByZero),但得到 EStackOverflow。
我们设法准备了非常简单的示例:ComError示例 http://programisci.instalsoft.com/MB/ComErrorExample/ComErrorExample.zip
有一个.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:我已经通过恢复浮点配置扩展了示例。