DLL関数を使ったプログラムを動かしたんですが、ERRORが解決できず
困っています。DLLを作成したのはいいのですが、それをLoadLibraryで読み込もうとしても指定したプロシージャが見つからないというエラーになるようです。使用している環境はVisual Studio.NET2003です。
以下はDLLのソースです。
// plug.c //
#include <windows.h>
#include <stdio.h>
__declspec(dllexport) void CALLBACK TestFunc()
{
printf("DLLのTestFunc()関数が実行されました。\n");
}
これをビルドするとplug.dllとplug.expとplug.libが作成されました。
そしてこれを使用したプログラムが
// stab.c //
#include <windows.h>
#include <stdio.h>
typedef void (*TestFunc)(void);
void main()
{
HMODULE hModule;
DWORD error;
TestFunc funcPointer;
hModule = LoadLibrary(TEXT("plug"));
error = GetLastError();//error値が127
funcPointer = (TestFunc)GetProcAddress(hModule,TEXT("TestFunc"));
funcPointer();
FreeLibrary(hModule);
getchar();
}
LoadLibrary関数を使用してアプリのメモリ空間にDLLを読み込もうとしているんですが、ここでハンドルが正確に渡されていないみたいなんです。どうしてこうなるのか分かりません。わかる方いらっしゃったらよろしくお願いします。
No.1
- 回答日時:
こんばんは。
指定しているDLL名の拡張子が抜けているのが原因かもしれません。
↓拡張子を付けてみてください。
hModule = LoadLibrary(TEXT("plug.dll"));
↓更に、関数ポインタにDLL側のエクスポート関数と同じ呼び出し規約を指定しましょう。
typedef void (CALLBACK *TestFunc)(void);
この回答への補足
修正して、typedef void (CALLBACK *TestFunc)(void);にし、
拡張子も.dllにしたんですが、funcPointer();を実行しようとすると
ERRORになります。まだプロシージャが見つけられないみたいです。
ディレクトリにはちゃんとplug.dllが入っているんですが・・・
No.3
- 回答日時:
plug.dllをDependency Walkerで開いて…
TestFuncという名前の関数がエクスポートされていますか?
__declspec(dllexport)でエクスポートした場合、関数名がそのままにはならなかったと思いますが…。
内部ンク用に名前が変更されているかと思われます。
defファイルを使用された方がよいかと。
この回答への補足
Dependency Walkerという(ソフト?)ものがないです。
defファイルというものも、よく分からないです。
よろしければ、それがどういう物か教えていただけると助かります。
No.4
- 回答日時:
>hModule = LoadLibrary(TEXT("plug"));
>error = GetLastError();//error値が127
GetLastErrorを見る前に、hModuleの値はどうなっているのでしょうか?
>__declspec(dllexport)でエクスポートした場合、関数名がそのままにはならなかったと思いますが…。
>内部ンク用に名前が変更されているかと思われます。
>defファイルを使用された方がよいかと。
defファイルを使う以外に、extern"C"を使う方法もありますね。
extern "C"{
__declspec(dllexport) void CALLBACK TestFunc();
}
__declspec(dllexport) void CALLBACK TestFunc()
{
printf("DLLのTestFunc()関数が実行されました。\n");
}
でよかったかな。
extern "C"{
__declspec(dllexport) void CALLBACK TestFunc(void);
}
__declspec(dllexport) void CALLBACK TestFunc(void)
{
printf("DLLのTestFunc()関数が実行されました。\n");
}
こっちのほうがいいかも。
この回答への補足
その方法を試したところERRORが起きました。
cファイルだったからだと思うのですが。リンケージ指定はC++だと出来るんですけどね。
hModuleの値は0x10000000でした。関数自体は失敗していなんでしょうか。
No.5
- 回答日時:
既に回答にもありますがGetLastErrorで原因は明らかです。
hModuleには恐らくNULLが入っているでしょう?dllはまずカレントディレクトリを検索しますが
VisualStudioの初期設定で実行した場合、
カレントディレクトリとexeの出力されたディレクトリが違います。
それが原因ではないでしょうか?
試しにplug.dllをcドライブのルートにコピーして
hModule = LoadLibrary(TEXT("C:\\plug.dll"));
とフルパスで指定してみたらどうでしょうか?
この回答への補足
フルパスにしても同じことが起こりました。
あと、hModuleに入った値ですが0x10000000です。
funcPointer = (TestFunc)GetProcAddress(hModule,TEXT("TestFunc"));
ここでfuncPointer にNULL(0x000000)が入っています。
関数が失敗していました。
やっぱりLoadLibraryに原因があると思います。
No.6
- 回答日時:
> hModuleの値は0x10000000でした。
関数自体は失敗していなんでしょうか。NULLが返ってきているのではない限り、失敗ではありません。
> ここでfuncPointer にNULL(0x000000)が入っています。
ということは、LoadLibraryではなく、GetProcAddressの失敗です。
GetProcAddressの直後にGetLastErrorをするべきですね。
>Dependency Walkerという(ソフト?)ものがないです。
DLLをエクスプローラ上から右クリックしたときに、メニューに「View Dependencies」という項目はないでしょうか?
この回答への補足
Dependency Walkerを検索したところ、フリーで配布されていました。
これをDLして早速plug.dllを調べてみると関数名が_TestFunc@0になっていました。
リンク時チェックサムが0x00000000で要求ベースアドレスが0x10000000です。
なのでLoadLibrary()呼ぶとhModuleの値は0x10000000
_TestFunc@0でGetProcAddressを呼ぶと値にはちゃんと入っていました。
No.7ベストアンサー
- 回答日時:
このようなBBSで聞かれるよりは、
MSDNをご自分で調べられた方が遥かに
自分のためになると思いますが。。。
まず、モジュール名ですが、
LoadLibraryは第1パラメータでファイル名の拡張子を省略した場合、
既定の拡張子として「.DLL」が追加されます。
実行モジュールの取得に失敗した場合、
拡張エラー番号は126になります。
まずは今回の127というエラーが本当にLoadLibraryの後直ぐに
取得された拡張エラーなのかを教えてください。
#GetLastErrorは直前に実行した関数のエラーしか見れないので、
#タイミング的に書き換わっている可能性があります。
エラー的に127が返されたということは、
GetProcAddressのエラーである可能性が非常に高いです。
もしもGetProcAddress関数のエラーで返されたエラーならば、
DLL側がdefファイルを使用してビルドされていない可能性があります。
DEFファイルを使用しない場合、VC++はエクスポートする関数名を
修飾するためDLL側で用意した関数の関数名を指定するだけでは
アドレスを取得できません。
取得側はGetProcAddressに"_TestFunc@0"というような
修飾された「完全に明確な名前」を指定する必要があります。
#修飾子名はビルドするたびに異なる可能性があります。
これを回避する為の一番手っ取り早い方法は、
plug.defというファイルをプロジェクトに取り込み、
エクスポートする関数名を限定する方法があります。
--- plug.def -------------------------------
LIBRARY plug
EXPORTS
TestFunc @1
---ここまで----------------------------------
参考URL:http://msdn.microsoft.com/ja-jp/library/cc429241 …
この回答への補足
plug.def(モジュール定義)をプロジェクトに取り込んでTestFuncで実行したところERRORなく動作しました。defファイルを取り込んだお陰ですね。ありがとうございます。
しかし、GetLastError()で値を見てみると、値が127のままです。
何故こうなるのかはとても気になるのですが、一応は普通に動いています。
No.8
- 回答日時:
> plug.defというファイルをプロジェクトに取り込み、
言葉足らずですね。
defファイルを取り込むのは「DLL側のプロジェクト」です。
DLLのリビルドが必要です。
No.9
- 回答日時:
>フルパスにしても同じことが起こりました。
>あと、hModuleに入った値ですが0x10000000です。
そのときGetLastError()の値は0 (この操作は正しく終了しました。)になっていたはずです。
LoadLibrary()が成功すればGetLastErrorは0になります。
パスの指定も原因のひとつだったという事が考えられます。
No.10
- 回答日時:
> その方法を試したところERRORが起きました。
> cファイルだったからだと思うのですが。リンケージ指定はC++だと出来るんですけどね。
extern "C"{
__declspec(dllexport) void __cdecl TestFunc(void);
}
__declspec(dllexport) void __cdecl TestFunc(void)
{
printf("DLLのTestFunc()関数が実行されました。\n");
}
typedef void __cdecl (*TestFunc)(void);
だと、どうでしょうか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- その他(プログラミング・Web制作) IT初心者です 仕事で、vb.netで作成されたdllをvbaで呼び出すプログラムを作成しろと言われ 1 2023/03/27 08:22
- C言語・C++・C# Windows Formアプリからコンソールを呼び出して文字を出力させたい 8 2023/05/09 10:53
- C言語・C++・C# C言語 3 2022/10/04 15:07
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
- C言語・C++・C# カードシャッフルのブログラムを使ってc言語でブラックジャックをしたい 2 2022/04/12 15:13
- C言語・C++・C# Cのdoubleの浮動小数点表示について 3 2023/04/17 13:14
- ノートパソコン .dllファイルがありませんと表示される 5 2023/04/30 03:03
- C言語・C++・C# C言語初心者 構造体 課題について 2 2023/03/10 19:48
このQ&Aを見た人はこんなQ&Aも見ています
-
プロが教える店舗&オフィスのセキュリティ対策術
中・小規模の店舗やオフィスのセキュリティセキュリティ対策について、プロにどう対策すべきか 何を注意すべきかを教えていただきました!
-
DLLをGetProcAddress()で実行できない。
C言語・C++・C#
-
AfxLoadLibrary関数で、DLLのハンドルが取得できない
C言語・C++・C#
-
2回目からはLoadLibrary()がcnpdsdk.dll"を読み込み失敗する。"
C言語・C++・C#
-
-
4
DWORDの実際の型は何でしょうか
C言語・C++・C#
-
5
画面を強制的に再描画させる方法
C言語・C++・C#
-
6
deleteで開放するとエラーになる原因がわからない
C言語・C++・C#
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
python エラー
-
エクセルのエラーメッセージ「4...
-
fortranでプログラムを実行する...
-
バッチからsqlplusの接続エラー...
-
ビルド失敗 指定されたファイ...
-
Arduinoに関する質問
-
TeXのエラーメッセージ
-
適切な変換関数が存在しない???
-
error C3867 関数呼び出しには...
-
”_bstr_t”の使い方
-
vbaのインポートでエラー
-
Excelのエラーで困ってます。
-
VC++6.0からVC++2010への移行
-
SONY Readerで公開pdfを読む時...
-
cの標準関数openでNo such a f...
-
ERROR C2660について
-
sys/time.hのインクルードがで...
-
Handlesについて
-
C2146を回避するにはどうしたら...
-
デバッグ中のエラーのことで教...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
python エラー
-
エクセルのエラーメッセージ「4...
-
適切な変換関数が存在しない???
-
Excelのエラーで困ってます。
-
バッチからsqlplusの接続エラー...
-
fortranでプログラムを実行する...
-
HEWを使用しているのですが、こ...
-
コンパイルできません。
-
デバッグ中のエラーのことで教...
-
visual C++ でビルドの中止がで...
-
BC30002: 型 'ListItem' が定義...
-
Handlesについて
-
sys/time.hのインクルードがで...
-
ビルド失敗 指定されたファイ...
-
VB2008で定数に色の設定をした...
-
RightとLeft関数のライブ...
-
multiple definitionというエラー
-
WindowsからLinuxへの移植
-
HANDLEの宣言でのエラー
-
レコードセットをcloseする所で...
おすすめ情報