- 締切済み
AfxLoadLibrary関数で、DLLのハンドルが取得できない
はじめまして。 タイトルの通りですが、AfxLoadLibraryを使用して、DLLのハンドルを取得しようとしています。(取得したハンドルでGetProcAddress関数を使用する為) ここで、AfxLoadLibraryの戻り値となる、ハンドルがNULL(0x0000)となってしまい、GetProcAddressによる関数ポインタの設定が行えない状況となっています。 FormatMessage関数とGetLastErrorを使用し、原因を調べたところ、「指定されたモジュールが見つかりません」というメッセージとなりました。 AfxLoadLibraryで指定しているDLLについては、Exeファイルと同じフォルダ内に存在し、かつ、名前についても間違っていません。 試しに、別DLLを、上記NGとなるDLLと同様の名前で作成してみたところ、ハンドルの取得に成功したので、EXE側のコーディングミスという所は考えづらいところです。 お手数ですが、他の原因に心あたりがありましたらご教唆願います。 <コーディング(一部抜粋)> ---------------------------------------------------------------- HINSTANCE m_handle_Aaa; typedef WORD (WINAPI *LPOpenAaa)(); LPOpenAaa lpOpenAaa; BOOL DllLoad(void) { // Load Dll m_handle_Aaa = AfxLoadLibrary("AaaDLL.dll"); if(m_handle_Aaa < (HINSTANCE)HINSTANCE_ERROR) { PutLastError(); // Error Message return FALSE; } // Get Function Pointer lpOpenAaa = (LPOpenAaa)GetProcAddress( m_handle_Aaa, "OpenAaa"); if(lpOpenAaa == NULL) return FALSE; ・ ・ ・ ----------------------------------------------------------------
- みんなの回答 (3)
- 専門家の回答
みんなの回答
- redfox63
- ベストアンサー率71% (1325/1856)
パス無しの場合 1. EXEが読み込まれたフォルダ 2. カレントフォルダ の順に探すみたいですよ … WinXP SP2ですけど
- chie65536
- ベストアンサー率41% (2512/6032)
>m_handle_Aaa = AfxLoadLibrary("AaaDLL.dll"); http://msdn.microsoft.com/ja-jp/library/zzk20sxw(VS.80).aspx の「セキュリティに関するメモ」より --- Windows NT 4、Windows 2000、または Windows XP (SP1 以前) でコードを実行する場合は、必ず DLL の完全パス名を指定してください。これらのオペレーティング システムでファイルを読み込むと、最初に現在のディレクトリが検索されます。ファイルにパスが付いていないと、目的のものでないファイルが読み込まれる場合があります。 --- まず >Exeファイルと同じフォルダ内に存在し という事であれば、ここは「EXE自身の絶対パス付きファイル名を取得し、その文字列からファイル名を取り除き、DLL名を連結し、DLLの絶対パス付きファイル名を生成」して、それを引数に与える必要があります。 このままでは「プログラムが期待していない、同名の別DLL」をロードする可能性があり、その「同名の別DLL」にエントリポイント関数が存在しなかったり、エントリポイント関数がFALSEを返した場合、AfxLoadLibraryはNULL値を返します。 また「同名の別DLL」が偶然にロード出来てしまった場合、何が起きるかは判りません。 因みに >m_handle_Aaa = AfxLoadLibrary("AaaDLL.dll"); のような「パス無し」の場合「カレントディレクトリ」が1番最初に検索されます。 この「カレントディレクトリ」は、実行ファイルがある場所とは限りません。 一部のコンパイラでは「実行時の作業ディレクトリ(つまり、実行時のカレントディレクトリ)」を「EXEファイルと別のディレクトリ」に指定する事も可能です。 また、実行ファイルへのショートカットアイコンを作り、そのショートカットアイコンの「作業ディレクトリ」を「実行ファイルがあるフォルダと別のフォルダ」にして、ショートカットアイコン経由で実行ファイルを起動した場合「カレントディレクトリは実行ファイルがあるフォルダと別のフォルダ」になります。 そのような状況で「EXEがあるフォルダが検索パスのリストにない」場合は「EXEがあるフォルダは検索されない」ので「EXEがある場所にDLLを置いても読み込めない」と言う事が起きます。 そうなると「質問者さんのコーディングでは、DLLが読み込めないか、誤って同名の別DLLを読み込んでしまう」事になり、非常に危険です。 つまり >m_handle_Aaa = AfxLoadLibrary("AaaDLL.dll"); と言う書き方は「セキュリティ上、非常に危険」なのです。 EXE自身の絶対パス付きファイル名を取得するなどし、必ず「(動的に作成した)絶対パス付きファイル名」で指定しましょう。 >試しに、別DLLを、上記NGとなるDLLと同様の名前で作成してみたところ、ハンドルの取得に成功したので、 その「別DLL」は「EXEがあるフォルダから読んだとは限らない」ので、読み込めてしまう可能性があります。 >EXE側のコーディングミスという所は考えづらいところです。 「パス無しでDLLを指定している」と言う、明らかな「EXE側のコーディングミス」です。
お礼
解答ありがとうございます。 「セキュリティに関するメモ」参照いたしました。 完全パス指定をしなければならない事については、 認識がありませんでした。 同名の別DLLをロードしている可能性があるようですので 上記を参考に、修正してみます。 ありがとうございます。
- redfox63
- ベストアンサー率71% (1325/1856)
DLL側の DLLMainでul_reason_for_callがDLL_PROCESS_ATTACHのときにFALSEを返したりしていませんか?
お礼
解答ありがとうございます。 参照先DLLのソースを確認しましたが、 "TRUE"を返しておりました。
お礼
お返事遅れました。 ありがとうございます。