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 を返しました。
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>
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) と
書いてもいいんですね。
ありがとうございました。
ありがとうございます。
アンダースコアが付くというのは、目に見えないけど
WINAPI を付けないと内部的に _MyFunc になってしまっていたんですね。
プロシージャが見つからないと言われたのもinthefloiさんの説明で
分かりました。
動作確認ありがとうございます。
残った問題は BCC32 でのDLL関係のリンクのソースと
コンパイルスイッチだと思います。
No.2
- 回答日時:
WINAPI を付けるとエクスポート名の最初のアンダースコアが消えると思います。
extern "C" int WINAPI __declspec(dllexport) MyFunc(int, int);
それで mymain 側にも WINAPI を付けてあげる。
typedef int WINAPI (*FUNCTYPE)(int, int);
ありがとうございます。
アンダースコアが消えるという意味を教えてください。
__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 はプロシージャではなくて関数だと思うんだけど、
プロシージャが見つからないと言うなんておかしなエラーだと思いました。
No.1
- 回答日時:
よくは分からないんですが、
・せっかく書いているのですから GetLastError() を調べましょう
・動的にロードするのに、コンパイルで mydll.obj があるのは不自然
といったあたりが怪しげ
ごめんなさい。エラーナンバーを書き忘れていました。
GetLastError( ) は 6 を返します。
6 はハンドルが無効という意味らしいです。
C:\bcc32 -W mymain mydll.obj
を
C:\bcc32 -W mymain
にしてコンパイルしたけど、結果は同じでした。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
「指定されたキャストは有効で...
-
C言語での引数の省略方法
-
複数桁10進数の*桁目だけを抽出...
-
#define _CRT_SECURE_NO_WARNIN...
-
実数の整数部,小数部の取得
-
std::set<int> で、ある値が何...
-
return 1L
-
c言語の配列を使ってサイコロを...
-
Win32APIで作るコンボボックス...
-
構造体の勉強中です 合計点の高...
-
C言語で三目並べをするプログラ...
-
(int *)の意味
-
【C++】関数ポインタの使い方
-
int型の変数値をバイト列として...
-
HANDLEて何ですか?
-
if と配列の組み合わせ
-
C2601 ローカル関数の定義について
-
PowerShellがうまくいかない
-
構造体にたいして、ビット演算...
-
メルセンヌ・ツイスタの乱数生...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
「指定されたキャストは有効で...
-
C言語での引数の省略方法
-
#define _CRT_SECURE_NO_WARNIN...
-
AtCoderABC135の問題Cについて
-
C言語 エラーの原因がわからな...
-
複数桁10進数の*桁目だけを抽出...
-
【C++】関数ポインタの使い方
-
実数の整数部,小数部の取得
-
ラップ関数とはどんなものですか?
-
if と配列の組み合わせ
-
return 1L
-
read関数をノンブロッキングで...
-
(int *)の意味
-
std::set<int> で、ある値が何...
-
Win32APIで作るコンボボックス...
-
C++でvectorにテキストファイル...
-
「{ } で囲むだけ」は正しい?
-
足して100になるような乱数のア...
-
Arduinoのプログラムにエラーが...
-
課題でつまってます・・・
おすすめ情報