お世話になっております 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側及びそれを呼び出すプロセス側のソース共に追加したりもしたのですが結果は同じでした。
何か他に見るべき点はどこがあるでしょうか?
ご教授のほどよろしくお願い致します<(_ _)>
VCのツールに Dependency Walker があれば、対象の DLL で
ちゃんと "a" という名前で関数が存在するか確認してみてはどうでしょうか?
(a@〜見たいになっていませんか?)
場合によってはDLL作成時にdefファイルが必要になるかと思います。
(Libファイルをつかう場合とはことなるので)
補足です。
この前にも一つ簡易な 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
Blueさん、早々と回答ありがとうございます。
ちょうど入れ違いになってしまいました。
>場合によってはDLL作成時にdefファイルが必要になるかと思います。
def ファイルに関しましては"補足〜"スレのほうで記述してあるまんまになります。
>VCのツールに Dependency Walker があれば、対象の DLL で
>ちゃんと "a" という名前で関数が存在するか確認してみてはどうでしょうか?
そんな便利なものがあるのですね。
入っているか探してみます。
dumpbin /EXPORTS xxx.dll でも見えると思われ。
Dependency Walkerなるものを試してみました。
今回ロードしようとしている DLL で OPEN してみました。
他 DLL(USER32.DLLやKERNEL32.DLL等)では「Function」欄に各関数名が一覧表示されます。(こんなものがあったなんてぇ)
目的の DLLでは、Blueさんのおっしゃられる通り、"?関数名@@YGXXZ"とかいうものになっていました。。。
こ、これは・・・
DLLの作りそのものが悪いってことですかねorz
>dumpbin /EXPORTS xxx.dll でも見えると思われ。
επιστημηさん回答ありがとうざいます。
こっちでもいけるんですね。
コマンドラインなんて ping くらいしか使わないダメっ子です。
#Windows時代しか味わったことないっす
DEFファイルでちゃんと関数名をエクスポートしておけばいいです。
http://www.microsoft.com/japan/developer/library/vccore/_core_export_from_a_dll_using_..def_files.htm
また、
> "?関数名@@YGXXZ"
を GetProcAddress で指定すればいけるはずです。
Blueさんありがとうございます。
無事解決致しました。
その関数名に対するきちっとしたエクスポートが必要なのですね。
また、__declspec( dllexport ) する際にも exturn "C" が抜けていました。
前回はちゃんとやっていたのにorz
DEFファイルにも EXPORTS 文をきちっと入れておきました。
便利なツール情報もありがとうございました<(_ _)>
ツイート | ![]() |