
はじめまして、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で質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# スタックフレームの消滅 6 2023/05/20 12:33
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# c言語でユーザ関数を利用して入力された文字列を反転させるプログラムを作りたいです。 3 2023/01/29 19:47
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# const char** p;のとき、free(p)でC4090エラーとなるのはなぜですか 3 2023/03/31 16:28
- C言語・C++・C# カードシャッフルのブログラムを使ってc言語でブラックジャックをしたい 2 2022/04/12 15:13
- C言語・C++・C# C言語で再起関数とポインタを用いて文字列反転をする方法がわかりません。 4 2023/04/29 20:32
- C言語・C++・C# c言語でユーザ関数を利用して複素数のべき乗と絶対値の数列を計算するプログラムが作りたいです。 3 2023/01/29 22:13
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
戻り値を返す関数の前に(void)...
-
既定のコンストラクタがありま...
-
C#でテンキーの操作は可能でし...
-
多重定義が起きている?--lnk20...
-
静的でないメンバ関数の呼び出...
-
リージョンのフレームを描画す...
-
関数名の名前の衝突について。
-
C++にてtemplateで受け取った任...
-
DLLの関数呼び出しで引数がある...
-
C言語 extern について
-
C言語 int main(void) main()
-
privateなnamespaceメンバ
-
関数の戻り値にその関数のポイ...
-
PowerShellにてツリービュー入...
-
Aの値からBの値を除するとは??
-
fgetsなどのときのstdinのバッ...
-
「指定されたキャストは有効で...
-
Enterキーを押されたら次の処理...
-
java初心者です。入力されたの...
-
C言語のステップ数をカウントす...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
【gcc・cygwin】multiple defin...
-
多重定義が起きている?--lnk20...
-
const_castのつかいどころを教...
-
C++にてtemplateで受け取った任...
-
既定のコンストラクタがありま...
-
戻り値を返す関数の前に(void)...
-
静的でないメンバ関数の呼び出...
-
int main()、void main()、void...
-
C# KeyDownイベントでショート...
-
C# Controls.Addで動的に配置し...
-
(void)0 はどんな意味ですか
-
gcc: incompatible pointer type
-
_beginthreadにて発生するコン...
-
C#でラジオボタンを設定に記録...
-
C#でテンキーの操作は可能でし...
-
C++別のオブジェクトからメンバ...
-
CTabCtrl:TABインデックス単位...
-
見た目は同じソースなのにエラ...
-
pictureboxの画像を削除するには?
-
【VC++6.0】イベントハンドラ関...
おすすめ情報