• ベストアンサー

bcc32 GetProcAddress( )

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 を返しました。

質問者が選んだベストアンサー

  • ベストアンサー
noname#30727
noname#30727
回答No.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> typedef int 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; }

A__
質問者

お礼

ありがとうございます。 アンダースコアが付くというのは、目に見えないけど WINAPI を付けないと内部的に _MyFunc になってしまっていたんですね。 プロシージャが見つからないと言われたのもinthefloiさんの説明で 分かりました。 動作確認ありがとうございます。 残った問題は BCC32 でのDLL関係のリンクのソースと コンパイルスイッチだと思います。

A__
質問者

補足

できました。 少しずつソースを変えて実験していたら、いつのまにか できるようになりました。下に書いたソースでもできました。 どこかでくだらないミスをしていたんだと思います。 DLL内の関数を使う部分は (*ft)(7, 8) を ft(7, 8) と 書いてもいいんですね。 ありがとうございました。

その他の回答 (2)

noname#30727
noname#30727
回答No.2

WINAPI を付けるとエクスポート名の最初のアンダースコアが消えると思います。 extern "C" int WINAPI __declspec(dllexport) MyFunc(int, int); それで mymain 側にも WINAPI を付けてあげる。 typedef int WINAPI (*FUNCTYPE)(int, int);

A__
質問者

お礼

ありがとうございます。 アンダースコアが消えるという意味を教えてください。 __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 はプロシージャではなくて関数だと思うんだけど、 プロシージャが見つからないと言うなんておかしなエラーだと思いました。

  • a-kuma
  • ベストアンサー率50% (1122/2211)
回答No.1

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

A__
質問者

お礼

ごめんなさい。エラーナンバーを書き忘れていました。 GetLastError( ) は 6 を返します。 6 はハンドルが無効という意味らしいです。 C:\bcc32 -W mymain mydll.obj を C:\bcc32 -W mymain にしてコンパイルしたけど、結果は同じでした。

関連するQ&A