0

我已经在我的项目中广泛使用 ESENT,我真的很喜欢它的简单和快速。也很稳定!!

但我对 Windows 8 有一个大问题!!!每当我调用 JetSetSystemParameter 以外的东西时,无论我如何链接到 esent.dll(动态或静态),dll 都会崩溃,将我的应用程序拖下悬崖。

不幸的是,我仍然无法让它运行。我的代码在 Windows 7 或更早版本上运行没有问题。但是在 Windows 8 中,当我尝试创建实例(浮点无效操作)时,esent.dll 崩溃。

我尝试了所有可能的调用约定。这绝对不是问题。我尝试了更多并发现了这种奇怪的情况: 1. 我使用 VS 2012 创建了一个演示应用程序,并且 JetCreateInstance 工作得很好。2.在Delphi XE3中完全相同的代码会发送esent.dll崩溃。3.我使用VS 2012创建了一个DLL,导出了在上述演示应用程序中完美运行的方法,认为这是一个Delphi错误。4. 然后我将 DLL 加载到一个演示 Delphi 项目中(尝试使用 6、XE2 和 XE3)。调用方法和 BOOM。同样的崩溃。

现在我的假设是微软不会允许?!?与 esent.dll 一起正常工作的任何其他开发人员环境。这可能吗???

4

1 回答 1

5

该错误是浮点无效操作,使问题听起来好像与浮点控制字有关。

默认情况下,Delphi 不屏蔽浮点异常。因此,当代码要求浮点单元执行导致错误的操作时,FPU 会发出信号,然后将其转换为异常。

但大多数其他 Windows 开发环境在 FPU 上掩盖了这些异常。此类代码是在执行环境屏蔽了 FPU 异常的假设下编写的。但是如果你从 Delphi 调用一个 DLL,执行环境将有未屏蔽的 FPU 异常,打破了这个假设。我怀疑如果你屏蔽 FPU 异常,那么你的问题就会消失。

要测试这是否是问题所在,您可以简单地将其添加到您的代码中,并在其生命周期的早期执行:

Set8087CW($027F);

这将屏蔽所有异常并将 FPU 控制字设置为默认的 Windows 设置。

从长远来看,您可能希望在每次调用此 DLL 之前屏蔽异常,然后在对 DLL 的调用返回时恢复 FPU 控制字。

使用 Delphi 提供的库,这是一个稍微危险的游戏,因为Set8087CW它使用全局变量而不是线程安全的Default8087CW。如果您想了解有关该问题的更多信息,请参阅QC#107411

于 2013-03-26T12:42:25.073 回答