電子書籍の厳選無料作品が豊富!

 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を読み込もうとしているんですが、ここでハンドルが正確に渡されていないみたいなんです。どうしてこうなるのか分かりません。わかる方いらっしゃったらよろしくお願いします。

A 回答 (17件中11~17件)

> plug.defというファイルをプロジェクトに取り込み、


言葉足らずですね。
defファイルを取り込むのは「DLL側のプロジェクト」です。
DLLのリビルドが必要です。
    • good
    • 1

> 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を呼ぶと値にはちゃんと入っていました。

補足日時:2008/12/02 16:27
    • good
    • 0

既に回答にもありますが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に原因があると思います。

補足日時:2008/12/02 13:53
    • good
    • 0

>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でした。関数自体は失敗していなんでしょうか。

補足日時:2008/12/02 14:01
    • good
    • 0

plug.dllをDependency Walkerで開いて…


TestFuncという名前の関数がエクスポートされていますか?

__declspec(dllexport)でエクスポートした場合、関数名がそのままにはならなかったと思いますが…。
内部ンク用に名前が変更されているかと思われます。
defファイルを使用された方がよいかと。

この回答への補足

  Dependency Walkerという(ソフト?)ものがないです。
defファイルというものも、よく分からないです。
  よろしければ、それがどういう物か教えていただけると助かります。

補足日時:2008/12/02 10:32
    • good
    • 0

>error = GetLastError();//error値が127


#define ERROR_PROC_NOT_FOUND 127 //指定されたプロシージャが見つかりません。
と言う訳で、LoadLibrary()に指定した「plug」が見付からないのが原因です。
「plug」を「plug.dll」に変えましょう。

この回答への補足

plug.dllに変えても結果が同じでした。
個人的にはplug.expとplug.libが関係しているのかなと思うのですが。

補足日時:2008/12/02 00:59
    • good
    • 0

 こんばんは。


 指定しているDLL名の拡張子が抜けているのが原因かもしれません。

 ↓拡張子を付けてみてください。
 hModule = LoadLibrary(TEXT("plug.dll"));

 ↓更に、関数ポインタにDLL側のエクスポート関数と同じ呼び出し規約を指定しましょう。
 typedef void (CALLBACK *TestFunc)(void);

この回答への補足

修正して、typedef void (CALLBACK *TestFunc)(void);にし、
拡張子も.dllにしたんですが、funcPointer();を実行しようとすると
ERRORになります。まだプロシージャが見つけられないみたいです。
ディレクトリにはちゃんとplug.dllが入っているんですが・・・

補足日時:2008/12/02 00:56
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています