激凹みから立ち直る方法

mydll.cpp と mymain.cpp でDLL内の関数を使うテストを
しようとしたところです。
GetProcAddress( ) が失敗します。
どこを直せばいいか教えてください。


///////// mydll.cpp
#include <windows.h>

extern "C" __declspec(dllexport) int MyFunc(int, int);

int MyFunc(int a, int b){return( a + b );}


///////// mymain.cpp
#include <windows.h>

typedef int (*FUNCTYPE)(int, int);

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){

 HMODULE hModule;
 FUNCTYPE ft;
 int i;

 switch(msg){

 case WM_RBUTTONDOWN:
  hModule = LoadLibrary("mydll.dll");
  ft = (FUNCTYPE)GetProcAddress(hModule, "MyFunc");
  if(ft == NULL){
   //GetLastError();
  }
  i = (*ft)(7, 8);
 break;

 case WM_DESTROY:
  PostQuitMessage(0);
 break;

 default:
  return DefWindowProc(hWnd, msg, wParam, lParam);

 }
 return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int){
 ・・・
}


///////// コンパイル
C:\bcc32 -WD mydll
C:\bcc32 -W mymain mydll.obj


///////// 実行
LoadLibrary( ) は NULL 以外を返しました。
DLL_PROCESS_ATTACH は確認できました。
GetProcAddress( ) は NULL を返しました。

A 回答 (3件)

>アンダースコアが消えるという意味を教えてください。



デフォルトでは WINAPI を付けないと、関数 MyFunc のエクスポート名が "_MyFunc" になってしまうという意味です。

>プロシージャが見つからないと言うなんておかしなエラーだと思いました。

GetProcAddress は Get Procedure Address です。OS から見た場合、そのプログラムが C/C++言語で作られたかどうかは関係ないので、一般的にそう呼ばれていると思ってください。

あと、確認用に作ってみましたが、私の所では動いているようです。

///////// mydll.cpp
#include <windows.h>
BOOL WINAPI DllEntryPoint(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
return TRUE;
}
extern "C" int __declspec(dllexport) WINAPI MyFunc(int a, int b)
{
return a + b;
}

///////// mymain.cpp
#include <windows.h>
typedefint WINAPI (*FUNCTYPE)(int, int);
void mbox(LPCTSTR mess)
{
MessageBox(NULL, mess, "mymain", MB_OK);
}
int WINAPI WinMain(HINSTANCE i, HINSTANCE p, LPSTR c, int s)
{
HMODULE mydll = LoadLibrary("mydll.dll");
if (mydll) {
mbox("mydll.dll のロードに成功した");
FUNCTYPE myfunc = (FUNCTYPE)GetProcAddress(mydll, "MyFunc");
if (myfunc) {
mbox("MyFunc のアドレス取得に成功した");
char buff[256];
wsprintf(buff, "10 + 20 = %d", myfunc(10, 20));
mbox(buff);
}
else {
mbox("MyFunc のアドレス取得に失敗した");
}
FreeLibrary(mydll);
}
else {
mbox("mydll.dll のロードに失敗した");
}
return 0;
}

この回答への補足

できました。
少しずつソースを変えて実験していたら、いつのまにか
できるようになりました。下に書いたソースでもできました。
どこかでくだらないミスをしていたんだと思います。

DLL内の関数を使う部分は (*ft)(7, 8) を ft(7, 8) と
書いてもいいんですね。
ありがとうございました。

補足日時:2002/04/19 19:38
    • good
    • 0
この回答へのお礼

ありがとうございます。
アンダースコアが付くというのは、目に見えないけど
WINAPI を付けないと内部的に _MyFunc になってしまっていたんですね。

プロシージャが見つからないと言われたのもinthefloiさんの説明で
分かりました。

動作確認ありがとうございます。
残った問題は BCC32 でのDLL関係のリンクのソースと
コンパイルスイッチだと思います。

お礼日時:2002/04/19 18:56

WINAPI を付けるとエクスポート名の最初のアンダースコアが消えると思います。


extern "C" int WINAPI __declspec(dllexport) MyFunc(int, int);

それで mymain 側にも WINAPI を付けてあげる。
typedef int WINAPI (*FUNCTYPE)(int, int);
    • good
    • 0
この回答へのお礼

ありがとうございます。
アンダースコアが消えるという意味を教えてください。
__declspec を _declspec にするということですか?
_declspec もやってみたけど、結果は同じでした。
WINAPI を付けて、他の部分を少し直したけど、まだ
GetProcAddress( ) == NULL で悩んでいます。


///////// mydll.cpp
#include <windows.h>

extern "C" int WINAPI __declspec(dllexport) TestFunc(int, int);

int WINAPI MyFunc(int a, int b){return( a + b );}


///////// mymain.cpp
#include <windows.h>

typedef int (*FUNCTYPE)(int, int);

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){

 static HMODULE hModule;
 FUNCTYPE ft;
 int i;

 switch(msg){

 case WM_RBUTTONDOWN:
  hModule = LoadLibrary("mydll.dll");
  ft = (FUNCTYPE)GetProcAddress(hModule, "MyFunc");
  if(ft == NULL){
   char e[50];
   wsprintf(e, "%lu", GetLastError());
   MessageBox(hWnd, e, "GetProcAddress失敗", MB_OK);
  }
  i = (*ft)(7, 8);
 break;

 case WM_DESTROY:
  FreeLibrary(hModule);
  PostQuitMessage(0);
 break;

 default:
  return DefWindowProc(hWnd, msg, wParam, lParam);

 }
 return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int){
 ・・・
}


///////// コンパイル
C:\bcc32 -WD mydll
C:\bcc32 -W mymain


///////// 実行
LoadLibrary( ) は NULL 以外を返しました。
DLL_PROCESS_ATTACH は確認できました。
GetProcAddress( ) は NULL を返しました。
GetLastError( ) は 127 で、指定されたプロシージャが見つからなかった
という意味らしいです。それは mydll.dll から TestFunc が
見つからなかったということかな?
TestFunc はプロシージャではなくて関数だと思うんだけど、
プロシージャが見つからないと言うなんておかしなエラーだと思いました。

お礼日時:2002/04/18 07:06

よくは分からないんですが、



・せっかく書いているのですから GetLastError() を調べましょう
・動的にロードするのに、コンパイルで mydll.obj があるのは不自然

といったあたりが怪しげ
    • good
    • 0
この回答へのお礼

ごめんなさい。エラーナンバーを書き忘れていました。
GetLastError( ) は 6 を返します。
6 はハンドルが無効という意味らしいです。

C:\bcc32 -W mymain mydll.obj

C:\bcc32 -W mymain
にしてコンパイルしたけど、結果は同じでした。

お礼日時:2002/04/17 22:57

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