0

私は自分のプロジェクトにESENTを非常に広範囲に使用しており、ESENTがいかに簡単かつ高速に機能するかを本当に気に入っています。そして安定も!!

しかし、私はWindows8で大きな問題を抱えています!!! JetSetSystemParameter以外の何かを呼び出すたびに、esent.dllに(動的または静的に)リンクする方法に関係なく、dllがクラッシュし、アプリを崖から下ろします。

残念ながら、まだ実行できません。私のコードは、Windows7以前で問題なく実行できました。しかし、Windows 8では、インスタンスを作成しようとするとesent.dllがクラッシュします(浮動小数点の無効な操作)。

考えられるすべての呼び出し規約を試しました。これは間違いなく問題ではありません。さらに試してみたところ、この奇妙な状況が見つかりました。1. VS 2012を使用してデモアプリケーションを作成しましたが、JetCreateInstanceは正常に機能しました。2. Delphi XE3のまったく同じコードは、esent.dllをクラッシュさせます。3. VS 2012を使用してDLLを作成し、Delphiのバグだと思って、上記のデモアプリで完全に機能するメソッドをエクスポートしました。4.次に、デモDelphiプロジェクトにDLLをロードしました(6、XE2、およびXE3で試してみました)。メソッドとBOOMを呼び出しました。同じクラッシュ。

今私の仮定は、Microsoftが許可しないということですか?!?esent.dllで正しく動作する他の開発者環境。これは可能ですか?

4

1 に答える 1

5

エラー、つまり浮動小数点の無効な操作により、問題は浮動小数点制御ワードに関連しているように聞こえます。

デフォルトでは、Delphiは浮動小数点例外のマスクを解除します。したがって、コードが浮動小数点ユニットにエラーを引き起こす操作を実行するように要求すると、FPUは信号を送り、それが例外に変換されます。

ただし、他のほとんどのWindows開発環境では、FPUでこれらの例外がマスクされます。このようなコードは、実行環境でFPU例外がマスクされていることを前提に記述されています。ただし、DelphiからDLLを呼び出すと、実行環境でマスクされていないFPU例外が発生し、その仮定が破られます。FPUの例外をマスクすると、問題がなくなると思います。

これが問題であるかどうかをテストするには、コードにこれを追加して、コードの初期段階で実行します。

Set8087CW($027F);

これにより、すべての例外がマスクされ、FPU制御ワードがデフォルトのWindows設定に設定されます。

長期的には、このDLLを呼び出す前に例外をマスクし、DLLの呼び出しが戻ったときにFPU制御ワードを復元することをお勧めします。

Set8087CWこれは、グローバル変数を使用しているためスレッドセーフではないため、Delphiで提供されているライブラリを使用する少し危険なゲームですDefault8087CW。この問題について詳しく知りたい場合は、QC#107411を参照してください。

于 2013-03-26T12:42:25.073 に答える