DLLからの戻り値の受け取りでエラーが出ます

[戻る]
マルボロマン 2004/09/10(金) 19:59:50
こんにちは。

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 );
}



どなたかわかる方、助言よろしくお願いいたします。

dairygoods 2004/09/10(金) 21:43:38
> //EXEの呼び出し側
> typedef __declspec(dllimport) long(__cdecl* _GetInfo)();

呼び出し側は、「GetInfoは引数なし、戻り値はlong」と宣言しているのに、


> //----------InputInfo.dllのコード----------
> long GetInfo(long* Birthday, long* BloodType, long* Sex)

DLL側は、「GetInfoはlong*引数三つ、戻り値はlong」と宣言しています。

isshi 2004/09/10(金) 21:44:13
まず、
  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

シャノン 2004/09/10(金) 21:44:19
> a = GetInfo();    // DLLを起動

1. 引数を渡していません
2. a の型はあっていますか?

シャノン 2004/09/10(金) 21:45:09
わ、一分足らずの間に3人もw

マルボロマン 2004/09/12(日) 18:05:44
こんにちは。
ご返答ありがとうございます。

ご指摘通り引数がありませんでした。ありがとうございます。

それで、
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の書き(コピー)間違いでした。すみません。

isshi 2004/09/12(日) 22:34:04
>引数の宣言が間違っているのでしょうか?
間違っています。

>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 は型が間違っていますし、他の三つのポインタは
有効な値となっているのでしょうか?

isshi 2004/09/12(日) 22:35:40
間違えました。
>typedef void(__cdecl* _GetInfo)(long*, long*, long*);
typedef long(__cdecl* _GetInfo)(long*, long*, long*);

マルボロマン 2004/09/13(月) 10:13:27
[[解決]]
>>isshi様
ご指摘、ご教授ありがとうございます。
おかげさまでエラーも出ず、正常に処理が行なわれるようになりました。

本当にありがとうございました。

古いスレッドには追加発言できません。