
はじめまして、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;
}
***********************************************
以上
No.1ベストアンサー
- 回答日時:
呼び出し規約に相違があるため、渡す情報がずれてしまっているためでしょう。
stdcallをつけたらどうなりますか?
早速のご返事ありがとうございます。
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*);
として対処しました。
ありがとうございます。
大変助かりました。
No.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の乱用は不適切」です。
ありがとうございます。
「呼び出し規則」を知らずに CALLBACK を使用していました。
WINAPI を使用するようにしたいと思います。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
静的でないメンバ関数の呼び出...
-
コンパイルエラー: LNK2001
-
C言語 extern について
-
const_castのつかいどころを教...
-
戻り値を返す関数の前に(void)...
-
VC++でGetKeyboardStateがうま...
-
多重定義が起きている?--lnk20...
-
【VC++6.0】イベントハンドラ関...
-
関数名の名前の衝突について。
-
C++にてtemplateで受け取った任...
-
既定のコンストラクタがありま...
-
DLLの関数呼び出しで引数がある...
-
gcc: incompatible pointer type
-
【gcc・cygwin】multiple defin...
-
H8 3664Fのプログラム
-
C++ 静的クラスの役割が分からない
-
ウインドウの移動禁止
-
(void)0 はどんな意味ですか
-
int main()、void main()、void...
-
Delphiの定数とローカル変数の...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
【gcc・cygwin】multiple defin...
-
多重定義が起きている?--lnk20...
-
静的でないメンバ関数の呼び出...
-
C++にてtemplateで受け取った任...
-
const_castのつかいどころを教...
-
既定のコンストラクタがありま...
-
戻り値を返す関数の前に(void)...
-
C# KeyDownイベントでショート...
-
int main()、void main()、void...
-
C# Controls.Addで動的に配置し...
-
(void)0 はどんな意味ですか
-
C#でラジオボタンを設定に記録...
-
VC++でGetKeyboardStateがうま...
-
gcc: incompatible pointer type
-
クラス内で、親ではない他のク...
-
ウインドウの移動禁止
-
void*型の配列について
-
ドラッグしたときにマウスカー...
-
_beginthreadにて発生するコン...
-
C#でテンキーの操作は可能でし...
おすすめ情報