ある外部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)
これは実際に都度ロードされてしまっていて、私の思うようには動いて
いないということでしょうか?
またその場合、(静的リンク以外で)良い方法があればご教授願います。
ロードされるたびに該当するアドレスは変わるから、
ポインタを保存しておいても意味がないような。
ポインタの意味わかってるよね?
的外れだったらすまん
>モジュールのロード: MyLibrary.dll. デバッグ情報なし. ベースアドレス: $68B50000. プロセス My.exe (3268)
多分、DLL内で例外が出ている、EXEは$4000000台だから。
呼び出しは上手くいっているように思えるけど。
例外を出している関数は、実行中に[表示]→[デバッグ]→[モジュール]で
モジュール画面を出して、$68B50000が指している関数を探す。
もし指している関数がシステムのDLLならActiveXや特殊な型をパラメータにしているとか、呼び出し側が悪い可能性もある。
DLLがDelphiなら、DLLの方か起動してみるのも手だけど。
[実行]→[実行時引数]→"ホストアプリケーション"にEXEを設定。(動的はやったことないけど)
または、実行時に[実行]→[プロセスにアタッチ...]
こんにちは.
TMyFuncはどうなっているのですか?
>pFunc : TMyFunc; →グローバルな関数ポインタ変数
勘違いしてた。
>モジュールのロード: MyLibrary.dll. デバッグ情報なし. ベースアドレス: $68B50000. プロセス My.exe (3268)
>モジュールのアンロード : MyLibrary.dll. プロセス My.exe (3268)
のイベントログが何度も表示されるということか。
>pFunc(@param);
の実行は何度でも上手くいっているけど、その度にDLLがロードされる、でいいのかな?
アンロードの後に、モジュール画面やタスクマネージャーにそのDLLは存在しないの?
すみません、説明が足りませんでした。
いけ様が仰るとおりで、関数の呼出自体は成功しています。
ただ関数が実行されるたびに「ロード→アンロード」のログが出るので、
毎度毎度DLL自体がロードされ直されているのでは?と不安になりました。
>アンロードの後に、モジュール画面やタスクマネージャーにそのDLLは存在しないの?
そういえば…と思い当たって、GetProcAddressで関数を一度取得したあと
DLLファイル自体を削除してみました。
結果、それ以降も問題なく呼出は成功しました。
(再起動してDLLファイルが消された状態で呼び出すと、失敗します)
別にDLL自体がロードされ直されていたわけではないようです。
もっと早く気が付いて試してみるべきでした。お騒がせしました。
ツイート | ![]() |