■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上でもエラーを出さないプログラムにできます。
- main関数(WinMain)入った早々に CoInitialize関数を呼び出す
- ウィンドウを生成する。(ウィンドウハンドル有効)
- ウィンドウハンドルを必要とするモジュールの準備
- DirectX GraphicsやDirectSound, XAudio2など
- ShowWindow関数を実行
- (定常状態)
- 終了処理をした後、DestroyWindow関数を実行
- CoUninitialize関数を実行
- プログラム終了
Windows7で問題を発見、解決策の模索を行いましたが、
Windowsカーネルのバージョンを考えると、これらの問題発生はWindows Vistaでも同様に起こることが予想されます。
■まとめ
エラーが発生する人としない人の環境差として、IMEが絡んでいるところまでは突き止められましたが、まだ他の要因もあるのかもしれません。
発生しない人はMicrosoft IMEを使っていなかった、となると、使っていないユーザーはそんなに多いのかって疑問にもなります。
もしかしたら、IME2007だけが悪いのかもしれませんし…。