こんにちは。
OS;Windows XP HomeEdition、開発環境VC++6.0を使っております。
今回DLLで自分の誕生日、血液型、性別を入力して、入力された値をEXEに返すという
プログラムを作っていますが、戻り値が帰ってこないエラーが発生しました。
http://www.net24.ne.jp/~kenji/s_dll/dll2.html
↑こちらの「ライブラリ無しでDLLを呼び出す」というのを参考にして作りました。
コンパイルは無事通り、動きも入力までうまくいくのですが、戻り値を返す所で
「問題が発生したため、TestExe.exeを終了します」というエラーメッセージが出た後、
処理が止まってしまいます。(コードから実行時)
・EXE名;TestExe.exe
・DLL名;InputInfo.dll
以下のようなコードを書いています。
//----------TestExe.exeのコード----------
//EXEの呼び出し側
typedef __declspec(dllimport) long(__cdecl* _GetInfo)();
hDLL = LoadLibrary(InputInfo.dll); // DLL名
if( hDLL )
{
EF_InputUserInfo=(_GetInfo)GetProcAddress( hDLL, GetInfo );
}
void CInputTestDlg::OnButton1()
if( hDLL )
{
a = GetInfo(); // DLLを起動
}
//デストラクタ
CInputTestDlg::~CInputTestDlg()extern C _declspec(dllexport)
//----------InputInfo.dllのコード----------
long GetInfo(long* Birthday, long* BloodType, long* Sex)
{
// 入力ウインドウ
CInputWindow input;
// 入力の実行
input.DoModal();
*Birthday = input.GetYear() * 10000 + input.GetMonth() * 100 +
input.GetDay();
*BloodType = input.GetBloodType();
*Sex = input.GetSex();
return 0L;
}
{
if( hDLL )
FreeLibrary( hDLL );
}
どなたかわかる方、助言よろしくお願いいたします。
> //EXEの呼び出し側
> typedef __declspec(dllimport) long(__cdecl* _GetInfo)();
呼び出し側は、「GetInfoは引数なし、戻り値はlong」と宣言しているのに、
> //----------InputInfo.dllのコード----------
> long GetInfo(long* Birthday, long* BloodType, long* Sex)
DLL側は、「GetInfoはlong*引数三つ、戻り値はlong」と宣言しています。
まず、
typedef __declspec(dllimport) long(__cdecl* _GetInfo)();
で _GetInfo の指す対象となる関数の引数が void となっており、
エクスポートされている GetInfo の引数と一致していません。
また、今回の問題と直接関係ないかもしれませんが、
__declspec(dllimport) はいらないですし(あってもいいのかもしれません)
呼び出し規約は DLLの場合 __stdcall とするのが普通のようです。
(__stdcall とする理由については知らないので、知っている方がいましたらご教授いた
だけたら幸いです。)
また、当然、実際に関数を呼び出すときは
a = GetInfo(); // DLLを起動
ではだめで、正しい引数を渡さなければいけません。
(この GetInfo はいきなり出てきていますが、EF_InputUserInfo の誤りでしょうか?)
なお、ここのホームページにもDLLについて解説があります。
http://rararahp.cool.ne.jp/vc/vctips/dll.htm
> a = GetInfo(); // DLLを起動
1. 引数を渡していません
2. a の型はあっていますか?
わ、一分足らずの間に3人もw
こんにちは。
ご返答ありがとうございます。
ご指摘通り引数がありませんでした。ありがとうございます。
それで、
long* Birth;
long* BloodType;
long* Sex;
long* a;
typedef __declspec(dllimport) void(__cdecl* _GetInfo)( Birth, BloodType, Sex );
static HINSTANCE hDLL = NULL;
static _GetInfo GetInfo;
と修正して、呼び出し部も
if( hDLL )
a = GetInfo( Birth, BloodType, Sex );
と修正してみましたが、
・error C2165: 'left-side modifier' : 'left-side modifier' : データへのポインタは変
更できません。
・error C2491:'__GetInfo' : dllimport データ の定義は許されません。
・error C2071: '_GetInfo' : 記憶クラスは不正です。
・error C2064: 関数ポインタとして評価されない式を使って、関数を呼び出そうとしまし
た。
という4つのエラーが出てきました。
引数の宣言が間違っているのでしょうか?
よろしくお願いいたします。
>>isshi様
>>(この GetInfo はいきなり出てきていますが、EF_InputUserInfo の誤りでしょう
か?)
ご指摘通りEF_InputUserInfoはGetInfoの書き(コピー)間違いでした。すみません。
>引数の宣言が間違っているのでしょうか?
間違っています。
>typedef __declspec(dllimport) void(__cdecl* _GetInfo)( Birth, BloodType, Sex );
typedef void(__cdecl* _GetInfo)(long*, long*, long*);
また、
>long* Birth;
>long* BloodType;
>long* Sex;
>long* a;
については、a は型が間違っていますし、他の三つのポインタは
有効な値となっているのでしょうか?
間違えました。
>typedef void(__cdecl* _GetInfo)(long*, long*, long*);
typedef long(__cdecl* _GetInfo)(long*, long*, long*);
>>isshi様
ご指摘、ご教授ありがとうございます。
おかげさまでエラーも出ず、正常に処理が行なわれるようになりました。
本当にありがとうございました。