在Delphi项目中发生与Windows 8的崩溃

Fot*_* MC 0 delphi esent edb windows-8

我一直在为我的项目广泛使用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.这可能吗???

Dav*_*nan 5

错误(浮点无效操作)使问题听起来好像与浮点控制字有关.

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

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

要测试这是否是问题,您只需将其添加到您的代码中,在其生命的早期执行:

Set8087CW($027F);
Run Code Online (Sandbox Code Playgroud)

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

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

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