はじめに-長くて退屈な部分
(質問は最後にあります)
FPU制御ワードを変更し続けるサードパーティのCOMコンポーネントでひどい頭痛がします。
私の開発環境はWindowsとVisualC++ 2008です。通常のFPU制御ワードは、さまざまな条件で例外がスローされないように指定しています。_CW_DEFAULT
で見つかったマクロとfloat.h
、起動時にデバッガーで制御ワードを確認することで、これを確認しました。
COMオブジェクトを呼び出すたびに、制御ワードは戻り時に変更されます。これは簡単に防御できます。制御ワードをリセットするだけで、すべて問題ありません。問題は、COMコンポーネントがイベントシンクの呼び出しを開始したときです。イベント呼び出しを受信するとすぐに制御ワードをリセットすることでコードを保護できますが、イベント呼び出しから戻るとすぐに何もできません。
このCOMコンポーネントのソースはありませんが、作成者と連絡を取り合っています。私が彼から受けた反応は「え?」でした。彼は私が話していることについて少しも手がかりを持っていないと思うので、私はこれについて自分で何かをしなければならないのではないかと心配しています。彼のランタイム(DLLはすべて大文字のTで始まるシンボル名でいっぱいなので、DelphiまたはBorland C ++のいずれかだと思います)、または彼が使用している他のサードパーティのコードが問題の原因であると思います。彼のコードがFPU制御ワードを明示的に変更しているとは思いません。
それで、なにかお手伝いできますか?ビジネスの観点からは、このサードパーティコンポーネントを使用することが不可欠です。技術的な観点から、私はそれを捨てて、通信のプロトコルを自分で実装することができました。ただし、このプロトコルにはクレジットカード取引の処理が含まれるため、これは非常にコストがかかります。私たちは責任を負いたくありません。
コンポーネントの作成者に渡すことができる、ハックアラウンド、またはBorland製品のFPU設定に関するいくつかの有用な情報がどうしても必要です。
質問
何かできることはありますか?コンポーネントの作成者は、それを修正するために必要なものを持っていないと思います(彼のかなり無知な応答から判断して)。
私は自分の例外ハンドラーをインストールするというアイデアをいじくり回してきました。このハンドラーでは、ハンドラーの制御ワードをリセットし、Windowsに実行を続行するように指示します。でハンドラーをインストールしてみましSetUnhandledExceptionFilter()
たが、何らかの理由で例外がキャッチされません。
- なぜ例外をキャッチしないのですか?
- FPU例外のキャッチに成功し、FPU制御ワードをリセットし、何も起こらなかったので実行を続行させた場合、すべての賭けは無効になりますか?
アップデート
皆様のご提案に感謝申し上げます。私だけでなく、彼のコードの他の多くのクライアントの生活を楽にするために彼が何ができるかについて、著者に指示を送りました。私は彼に、でFPU制御ワードをサンプリングし、DllMain(DLL_PROCESS_ATTACH)
後で使用するために制御ワードを保存して、イベントハンドラーを呼び出し、呼び出しから戻る前にFPUCWをリセットできるようにすることを提案しました。
今のところ、誰かが興味を持っているなら、私はハックアラウンドを持っています。彼のコードに何が起こるかわからないので、ハックアラウンドは潜在的に悪いものです。彼がコードで浮動小数点数を使用していないという確認を以前に受け取ったので、FPU例外に依存するサードパーティのコードを除いて、これは安全であるはずです。
アプリに加えた2つの変更:
- メッセージポンプをラップする
WH_CALLWNDPROC
メッセージポンプがバイパスされるコーナーケースをキャッチするためにウィンドウフック( )を取り付けます
どちらの場合も、FPUCWが変更されているかどうかを確認します。ある場合は、にリセットし_CW_DEFAULT
ます。