
はじめまして、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ランキング
-
既定のコンストラクタがありま...
-
CTabCtrl:TABインデックス単位...
-
多重定義が起きている?--lnk20...
-
戻り値を返す関数の前に(void)...
-
ドラッグしたときにマウスカー...
-
_beginthread()の使用について
-
C++にてtemplateで受け取った任...
-
C#でトーンカーブの作成
-
void*型の配列について
-
静的でないメンバ関数の呼び出...
-
構造体を宣言と共に初期化する方法
-
最早開始時間と最遅完了時刻を...
-
Aの値からBの値を除するとは??
-
信頼区間の1.96や1.65ってどこ...
-
#define _CRT_SECURE_NO_WARNIN...
-
C言語 エラーの原因がわからな...
-
値差の%計算方法について
-
数字以外が入力されたらエラー...
-
「Aに対するBの割合」と「Aに対...
-
VB6.0での小数点の扱いについて
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
静的でないメンバ関数の呼び出...
-
既定のコンストラクタがありま...
-
戻り値を返す関数の前に(void)...
-
C++にてtemplateで受け取った任...
-
【gcc・cygwin】multiple defin...
-
const_castのつかいどころを教...
-
多重定義が起きている?--lnk20...
-
gcc: incompatible pointer type
-
(void)0 はどんな意味ですか
-
C# KeyDownイベントでショート...
-
pictureboxの画像を削除するには?
-
Notepad++の関数リスト表示の変...
-
C#でテンキーの操作は可能でし...
-
アドレスを指定して関数を呼び...
-
ウインドウの移動禁止
-
画面上をクリックするとクリッ...
-
C# Controls.Addで動的に配置し...
-
別ソースファイル、同クラス名...
-
DLLの関数呼び出しで引数がある...
-
プログラム作成教えてください...
おすすめ情報