LoadLibrary〜GetProcAddress時のエラー

解決


DD.  2006-02-07 23:01:36  No: 60675

お世話になっております DD.です

簡易なDLLを作成し、それを別プロセスから LoadLibrary() し、
GetProcAddress() で処理しようと試みました。

LoadLibrary()は問題なく、その後の GetProcAddress()で「指定されたプロシージャが見つからない」とのエラーが発生します。

尚、DLLからではなく、Libから静的に関数を呼び出すと問題ありません。

以下ソース抜粋)
(.dll)
#define DllExport __declspec( dllexport )
DllExport void a();
void a() {}

(.c++)
typedef void (*pfunc)();
HMODULE handle = LoadLibrary(...);
pfunc func = (pfunc)GetProcAddress( handle, "a" ); ←エラー

エラーの内容は GetLastError()から取得したものです。

LoadLibrary()が問題なく、関数のシグネチャも間違っていないと思います。
Libならば問題ないことから a() 関数も認識されてると思うのですが、
なぜエラーになるのか、他に見るべき点がわかりません。

また、
#define DllExport ...
DllExport void a();
部をヘッダにわけ、DLL側及びそれを呼び出すプロセス側のソース共に追加したりもしたのですが結果は同じでした。

何か他に見るべき点はどこがあるでしょうか?
ご教授のほどよろしくお願い致します<(_ _)>


Blue  2006-02-07 23:11:22  No: 60676

VCのツールに Dependency Walker があれば、対象の DLL で
ちゃんと "a" という名前で関数が存在するか確認してみてはどうでしょうか?
(a@〜見たいになっていませんか?)

場合によってはDLL作成時にdefファイルが必要になるかと思います。
(Libファイルをつかう場合とはことなるので)


DD.  2006-02-07 23:11:44  No: 60677

補足です。

この前にも一つ簡易な DLL を用いて他プロセスからアクセスするテストを行いました。
その内容は今回のものはまったく異なるものなのですが、LoadLibrary()からGetProcAddress()を使用するやり方は同じです。

そして、その時はうまくいき、今回のみエラーとなってしまい、皆さんのお力を貸して頂きたいと思ったところでございます。

前回と今回で違う点の一つとして、DLL内で共有としたい変数の定義があります。

前回は CreateFileMapping() と MapViewOfFile() を使用しました。
他プロセスから呼ぶ関数に関しては今回と同じように

#define DllExport ...

と、してヘッダに用意しました。(DLL・プロセス側の両方に入れてます)

今回は

#pragma data_seg( "..." )
共有変数の定義と初期化
#pragma data_seg()

とし、def ファイルを用意し、

LIBRARY "ファイル名"
SECTIONS
   ... READ WRITE SHARED

と、しています。

こういった共有変数の作成の仕方により、
"その共有変数を用いた関数"への呼び出し方が変わったりするのでしょうか?

環境

OS:XP VC++2005 Pro


DD.  2006-02-07 23:14:20  No: 60678

Blueさん、早々と回答ありがとうございます。

ちょうど入れ違いになってしまいました。

>場合によってはDLL作成時にdefファイルが必要になるかと思います。
def ファイルに関しましては"補足〜"スレのほうで記述してあるまんまになります。

>VCのツールに Dependency Walker があれば、対象の DLL で
>ちゃんと "a" という名前で関数が存在するか確認してみてはどうでしょうか?
そんな便利なものがあるのですね。
入っているか探してみます。


επιστημη  2006-02-07 23:17:44  No: 60679

dumpbin /EXPORTS xxx.dll でも見えると思われ。


DD.  2006-02-07 23:41:53  No: 60680

Dependency Walkerなるものを試してみました。
今回ロードしようとしている DLL で OPEN してみました。

他 DLL(USER32.DLLやKERNEL32.DLL等)では「Function」欄に各関数名が一覧表示されます。(こんなものがあったなんてぇ)

目的の DLLでは、Blueさんのおっしゃられる通り、"?関数名@@YGXXZ"とかいうものになっていました。。。

こ、これは・・・
DLLの作りそのものが悪いってことですかねorz

>dumpbin /EXPORTS xxx.dll でも見えると思われ。
επιστημηさん回答ありがとうざいます。

こっちでもいけるんですね。
コマンドラインなんて ping くらいしか使わないダメっ子です。
#Windows時代しか味わったことないっす


Blue  2006-02-07 23:59:56  No: 60681

DEFファイルでちゃんと関数名をエクスポートしておけばいいです。
http://www.microsoft.com/japan/developer/library/vccore/_core_export_from_a_dll_using_..def_files.htm

また、
> "?関数名@@YGXXZ"
を GetProcAddress で指定すればいけるはずです。


DD.  2006-02-08 00:12:34  No: 60682

Blueさんありがとうございます。

無事解決致しました。

その関数名に対するきちっとしたエクスポートが必要なのですね。

また、__declspec( dllexport ) する際にも exturn "C" が抜けていました。
前回はちゃんとやっていたのにorz

DEFファイルにも EXPORTS 文をきちっと入れておきました。

便利なツール情報もありがとうございました<(_ _)>


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

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






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