none
AfxGetInstanceHandleをコールすると落ちてします原因を探る方法 RRS feed

  • 質問

  • 表題について、悩んでおります。

    VS2008 C/C++にて作成しており、Win32DLL形式で作成しており、それにMFCを利用できるようにしている環境で開発しています。

    DLLがおかれれているフォルダーの位置を得るためにAfxGetInstanceHandleをコールするのですが、これをなぜか読んだ瞬間落ちてしまいます。原因はネットで検索すると、「MFCが初期化される前に呼び出すと失敗します」とありました。これだけで落ちている原因を特定するのは難しいとは思いますが、とかく何を最初に探ればよろしいでしょうか?


    2013年6月18日 23:21

回答

  • AfxGetInstanceHandle を呼び出すタイミングによって、失敗する場合もありますし、クラッシュしなくても意図した値が取得できない場合もあります。どこでどのように呼び出しているかわからないのでこれ以上は言及できません。

    ですので、まずは、デバッガでデバッグ実行し、その落ちる瞬間のコード位置でブレークさせましょう。直接的な原因がわかります。

    ところで、作成しているMFCのDLLは、通常DLL(MFCのDLLを利用するあるいは、MFCをスタティックリンクするのいずれかの形)でしょうか?それとも、拡張DLLでしょうか?

    拡張DLLの場合、AfxGetInstanceHandleでは、自身(DLL)のインスタンスハンドルを取得することはできません(拡張DLLは、自身のDLLのインスタンス情報を格納するCWinAppクラスを持たないため)。

    また、レギュラーDLL(通常DLL)の場合は、DLLのエクスポート関数の先頭で

    AFX_MANAGE_STATE( AfxGetStaticModuleState() );

    を呼び出す必要があります。詳しくは AFX_MODULE_STATE 構造体のリファレンスをお読みください。MFCが持つ境界を切り替える仕組みなので、これを怠るとわけのわからない挙動を示す場合があります(うまくいく場合もあるし、全然関係ないところでこれが理由でエラーになる場合もあります)。


    わんくま同盟,Microsoft MVP for Visual C++(Oct 2005-) http://blogs.wankuma.com/tocchann/

    • 回答としてマーク 星 睦美 2013年6月26日 5:55
    2013年6月19日 2:48

すべての返信

  •  1.AfxGetInstanceHandle()を、DLLの配置されたフォルダーを調べる目的で
      使用することはできません(というか本質的に無関係です)。

     2.MFCとスタティック(静的)リンクしたDLL「内」でAfxGetInstanceHandle()を
      実行した場合、そのDLLを使用している実行ファイルのインスタンスが、
      戻ります。

     3.上記以外の場合のDLL「内」でAfxGetInstanceHandle()を
      実行した場合、そのDLL自体のインスタンスが戻ります。

     4.EXE「内」でAfxGetInstanceHandle()を実行した場合、
      そのEXEのインスタンスハンドルが戻ります。

    一般に、実行ファイル(EXE/DLL)の起動パスを得るには、上記ハンドルを与えて、

     5.GetModuleFileName()を使用します。

    以上を踏まえた上で、何がどのようになったのか、もう一度説明してみてはどうでしょう。

    2013年6月19日 0:57
  • AfxGetInstanceHandle を呼び出すタイミングによって、失敗する場合もありますし、クラッシュしなくても意図した値が取得できない場合もあります。どこでどのように呼び出しているかわからないのでこれ以上は言及できません。

    ですので、まずは、デバッガでデバッグ実行し、その落ちる瞬間のコード位置でブレークさせましょう。直接的な原因がわかります。

    ところで、作成しているMFCのDLLは、通常DLL(MFCのDLLを利用するあるいは、MFCをスタティックリンクするのいずれかの形)でしょうか?それとも、拡張DLLでしょうか?

    拡張DLLの場合、AfxGetInstanceHandleでは、自身(DLL)のインスタンスハンドルを取得することはできません(拡張DLLは、自身のDLLのインスタンス情報を格納するCWinAppクラスを持たないため)。

    また、レギュラーDLL(通常DLL)の場合は、DLLのエクスポート関数の先頭で

    AFX_MANAGE_STATE( AfxGetStaticModuleState() );

    を呼び出す必要があります。詳しくは AFX_MODULE_STATE 構造体のリファレンスをお読みください。MFCが持つ境界を切り替える仕組みなので、これを怠るとわけのわからない挙動を示す場合があります(うまくいく場合もあるし、全然関係ないところでこれが理由でエラーになる場合もあります)。


    わんくま同盟,Microsoft MVP for Visual C++(Oct 2005-) http://blogs.wankuma.com/tocchann/

    • 回答としてマーク 星 睦美 2013年6月26日 5:55
    2013年6月19日 2:48
  • >成しているMFCのDLLは、通常DLL(MFCのDLLを利用するあるいは、MFCをスタティックリンクするのいずれかの形)でしょうか?それとも、拡張DLLでしょうか?

    該当部を調査しましたらば、「共有DLL」となっていました。これを「Windows標準」とすると落ちなくなりました。

    参考になりました。ありがとうございました。


    2013年6月24日 7:53