こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

DLLの関数呼び出しで引数があるとフリーズしてしまう。

はじめまして、C言語勉強中の初心者です。
現在、DLLに定義されている関数を呼び出すことを試していますが、うまくいかないので質問させて頂きました。

DLLには2つの関数が定義されています。
 1.void Hello()
 2.void HelloEx(char *pval);
1の関数を呼び出す場合は異常なく終了するのですが、2の関数を呼び出すと、フリーズしてしまいます。
フリーズする原因が分からないので、教えて頂ければと思います。

以下にソースを掲載します。
因みにコンパイラはBCC5.5.1を使用しています。
*****************************************************
DLL(Hello.c) [bcc32 -WD Hello.c]
*****************************************************
#include <windows.h>
#include <stdio.h>
__declspec(dllexport) void CALLBACK Hello(void) {
printf("Hello!\n");
}
__declspec(dllexport) void CALLBACK HelloEx(char *pVal) {
printf("Hello!%s\n", pVal);
}
*****************************************************
EXE(HelloTest.c)[bcc32 -L HelloTest.c]
*****************************************************
#include <windows.h>
#include <stdio.h>
typedef void (*Hello)(void);
typedef void (*HelloEx)(char*);
int main(void) {
HMODULEhMod;
Hellofunc;
HelloExfuncEx;

hMod = LoadLibrary( "Hello.dll" );
if(!hMod) return FALSE;

func = (Hello)GetProcAddress( hMod, "Hello");
if(!func) return FALSE;

funcEx = (HelloEx)GetProcAddress( hMod, "HelloEx");
if(!funcEx) return FALSE;

func();
funcEx("World");

FreeLibrary(hMod);

return 0;
}
***********************************************
以上

投稿日時 - 2009-06-08 17:01:47

QNo.5027283

困ってます

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

呼び出し規約に相違があるため、渡す情報がずれてしまっているためでしょう。
stdcallをつけたらどうなりますか?

投稿日時 - 2009-06-08 17:19:57

お礼

早速のご返事ありがとうございます。

DLL関数を呼び出すプログラムの関数のポインタの前にstdcallを付けたらうまくいきました!

具体的には
<HelloTest.c>
typedef void _stdcall (*HelloEx)(char*);
※アンダースコアが必要でした。

DLLの関数の定義ではCALLBACKを付けていたので、情報のズレが発生していたのでしょう。

DLLの定義と同じくCALLBACKを付けて、
<HelloTest.c>
typedef void CALLBACK (*Hello)(void);
typedef void CALLBACK (*HelloEx)(char*);

として対処しました。

ありがとうございます。
大変助かりました。

投稿日時 - 2009-06-08 17:49:15

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(2)

ANo.2

>DLLの関数の定義ではCALLBACKを付けていたので、情報のズレが発生していたのでしょう。
>DLLの定義と同じくCALLBACKを付けて、

DLL関数の呼び出し規則に「CALLBACK」を指定するのは適切ではありません。

BCCの場合、windef.hで定義されているCALLBACKは、本来「OS側からアプリケーション内の関数を呼び出す際の呼び出し規則」であり「アプリケーションがDLL関数を呼び出す際の呼び出し規則ではない」のです。

将来「OS側からアプリケーション内の関数を呼び出す際の呼び出し規則の仕様変更」があった場合、CALLBACKの意味を理解せずにCALLBACKを乱用すると、とても困った事になるでしょう。

DLL側、アプリ側の両方の呼び出し規則を、両方とも「CALLBACKからWINAPIに変更すべき」かと思います。

BCCでは、通常「Windows API関数」の殆どは「暗黙的なDLL関数の呼び出し」であり、一部の例外を除いて「DLL関数の呼び出し規則は、Windows API関数の呼び出し規則と同一で、呼び出し規則はWINAPIを使う」のが普通です。

ともかく「CALLBACKの乱用は不適切」です。

投稿日時 - 2009-06-09 12:39:40

お礼

ありがとうございます。
「呼び出し規則」を知らずに CALLBACK を使用していました。
WINAPI を使用するようにしたいと思います。

投稿日時 - 2009-06-16 13:55:41

あなたにオススメの質問