同じDLL内関数を動的に何度も呼び出す

解決


のりぺぃ  2010-06-11 03:13:19  No: 38652

ある外部DLL内の関数を、動的リンクで呼び出そうとしています。
この関数は何度も呼び出されるため、LoadLibrary→GetProcAddressで一度
取得した関数のポインタ変数を保存しておいて、使い回そうと考えました。

pFunc : TMyFunc;  →グローバルな関数ポインタ変数

// 一度だけ呼び出される処理
iHandle := LoadLibrary('MyLibrary.dll');
if (iHandle <> 0) then
begin
  pFunc := TMyFunc(GetProcAddress(iHandle, 'MyFunc'));
end;


// 別の場所で、関数実行
pFunc(@param);

関数は取得済みなので、何度もロードされないのではと思っていたのですが
pFuncを呼び出すたびに、以下の(デバッガの)イベントログが出力されます。
モジュールのロード: MyLibrary.dll. デバッグ情報なし. ベースアドレス: $68B50000. プロセス My.exe (3268)
モジュールのアンロード : MyLibrary.dll. プロセス My.exe (3268)

これは実際に都度ロードされてしまっていて、私の思うようには動いて
いないということでしょうか?
またその場合、(静的リンク以外で)良い方法があればご教授願います。


ポインタ  2010-06-11 03:57:41  No: 38653

ロードされるたびに該当するアドレスは変わるから、
ポインタを保存しておいても意味がないような。
ポインタの意味わかってるよね?

的外れだったらすまん


いけ  2010-06-11 21:24:30  No: 38654

>モジュールのロード: MyLibrary.dll. デバッグ情報なし. ベースアドレス: $68B50000. プロセス My.exe (3268)
多分、DLL内で例外が出ている、EXEは$4000000台だから。
呼び出しは上手くいっているように思えるけど。

例外を出している関数は、実行中に[表示]→[デバッグ]→[モジュール]で
モジュール画面を出して、$68B50000が指している関数を探す。
もし指している関数がシステムのDLLならActiveXや特殊な型をパラメータにしているとか、呼び出し側が悪い可能性もある。

DLLがDelphiなら、DLLの方か起動してみるのも手だけど。
[実行]→[実行時引数]→"ホストアプリケーション"にEXEを設定。(動的はやったことないけど)
または、実行時に[実行]→[プロセスにアタッチ...]


Mr.XRAY  2010-06-12 05:12:39  No: 38655

こんにちは.

TMyFuncはどうなっているのですか?

>pFunc : TMyFunc;  →グローバルな関数ポインタ変数


いけ  2010-06-14 03:33:49  No: 38656

勘違いしてた。
>モジュールのロード: MyLibrary.dll. デバッグ情報なし. ベースアドレス: $68B50000. プロセス My.exe (3268)
>モジュールのアンロード : MyLibrary.dll. プロセス My.exe (3268)
のイベントログが何度も表示されるということか。

>pFunc(@param);
の実行は何度でも上手くいっているけど、その度にDLLがロードされる、でいいのかな?

アンロードの後に、モジュール画面やタスクマネージャーにそのDLLは存在しないの?


のりぺぃ  2010-06-14 17:41:13  No: 38657

すみません、説明が足りませんでした。

いけ様が仰るとおりで、関数の呼出自体は成功しています。
ただ関数が実行されるたびに「ロード→アンロード」のログが出るので、
毎度毎度DLL自体がロードされ直されているのでは?と不安になりました。

>アンロードの後に、モジュール画面やタスクマネージャーにそのDLLは存在しないの?
そういえば…と思い当たって、GetProcAddressで関数を一度取得したあと
DLLファイル自体を削除してみました。
結果、それ以降も問題なく呼出は成功しました。
(再起動してDLLファイルが消された状態で呼び出すと、失敗します)
別にDLL自体がロードされ直されていたわけではないようです。
もっと早く気が付いて試してみるべきでした。お騒がせしました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加