本サイトでは、アフィリエイト広告およびGoogleアドセンスを利用しています。

NULL 参照ポインターがスタブに渡されました

■Windows7にしてからの挙動変化

DirectX関連のプログラムを作っていて、
「testApplication.exe の 0x776ab727 で初回の例外が発生しました: 0x000006F4: NULL 参照ポインターがスタブに渡されました。」
というメッセージを、VisualStudioの出力ウィンドウで見かけるようになりました。
それとアプリケーションの終了時に、ヒープが壊れています(下図)のメッセージが出てきたりとか。

アプリケーションの組み方にちょっと気をつけないといけないのでは?と思います。

またこのメッセージの発生条件については、ネットを調べてみてもいまいち理由が不明だったので、気合いを出して調べてみました。

■発生環境

  • Windows7 x64 Ultimate, Professional
  • VisualStudio2010,2008どちらのビルド環境でも起こる
  • DirectX(DirectSoundやXAudio2使っていたりするとより出くわす)
  • Microsoft Office IME 2007を使用

発生する環境として上記を満たしていることが条件です。

■原因

調べてみてわかったのは上記の環境で以下の2つを同時に満たす場合に発生しました。

  • Microsoft Office IME 2007を使用している
  • CoInitialize,CoUninitializeの呼出タイミングが悪い

どうやら ShowWindow関数を実行して、CoInitialize関数が実行されると、
「0x000006F4: NULL 参照ポインターがスタブに渡されました。」のエラーが発生します。
ShowWindow関数の前に CoInitialize関数を(1度は)実行しておく必要があります。
初回実行がShowWindowより後だとまずいってことです。

そして、それに対になるCoUninitialize関数もまた、同じようにDestroyWindow関数の後に実行する必要があります。
これも逆になると、ヒープが壊れています、のエラーを発生させる条件となります。

さらに、IMEの存在が上記の発生条件にかかわってきます。
これがATOKを普段使用している環境だと上記のエラーが発生しないようです。

■対処方法

理由のところでしっかり書いてしまいましたが、
プログラム中で以下の手順を守ることで、Windows7上でもエラーを出さないプログラムにできます。

  1. main関数(WinMain)入った早々に CoInitialize関数を呼び出す
  2. ウィンドウを生成する。(ウィンドウハンドル有効)
  3. ウィンドウハンドルを必要とするモジュールの準備
    1. DirectX GraphicsやDirectSound, XAudio2など
  4. ShowWindow関数を実行
  5. (定常状態)
  6. 終了処理をした後、DestroyWindow関数を実行
  7. CoUninitialize関数を実行
  8. プログラム終了

Windows7で問題を発見、解決策の模索を行いましたが、
Windowsカーネルのバージョンを考えると、これらの問題発生はWindows Vistaでも同様に起こることが予想されます。

■まとめ

エラーが発生する人としない人の環境差として、IMEが絡んでいるところまでは突き止められましたが、まだ他の要因もあるのかもしれません。
発生しない人はMicrosoft IMEを使っていなかった、となると、使っていないユーザーはそんなに多いのかって疑問にもなります。
もしかしたら、IME2007だけが悪いのかもしれませんし…。

DirectXプログラミング
すらりんをフォローする
すらりん日記
タイトルとURLをコピーしました