[解決済み] Windowsで__cdeclと__stdcallのどちらを使うか?
質問
私は現在 Windows 用の C++ ライブラリを開発しており、DLL として配布される予定です。より正確には、私の DLL 内の関数は、DLL を再コンパイルすることなく、MSVC++ および MinGW の複数のバージョンでコンパイルされたコードから使用可能である必要があります。しかし、どの呼び出し規則が最適なのか混乱しています。
cdecl
それとも
stdcall
.
時々、quot; the C calling convention is the only one guaranteed to be same accross compilers" というような発言を耳にしますが、これは " のような発言とは対照的です。
の解釈にはいくつかのバリエーションがあります。
cdecl
の解釈にはいくつかのバリエーションがあり、特に値を返す方法には
"を返す方法についてです。これは、特定のライブラリ開発者(たとえば
libsndfile
のような) 特定のライブラリ開発者が、配布する DLL で C の呼び出し規約を使用することを、目に見える問題なしに止めることはできないようです。
一方
stdcall
の呼び出し規約はよく定義されているようです。私が聞いたところでは、すべての Windows コンパイラは、Win32 と COM で使用される規約であるため、基本的にこれに従うことが要求されるようです。これは、Win32/COMをサポートしないWindowsコンパイラは、あまり有用ではないという前提に基づいています。フォーラムに投稿された多くのコード・スニペットは、関数を次のように宣言しています。
stdcall
と宣言していますが、私は
なぜ
.
あまりにも多くの矛盾した情報があり、検索するたびに異なる答えが返ってくるので、2 つのうちどちらかを決めるのにあまり役に立ちません。私は、なぜどちらかを選ぶべきなのか (または、なぜ 2 つが同等なのか) について、明確で詳細な、論拠のある説明を探しているのです。
この質問は、quot;classic" 関数に適用されるだけでなく、仮想メンバー関数呼び出しにも適用されることに注意してください。 ここで と そこ ).
どのように解決するのですか?
私はちょうどいくつかの実際のテスト (MSVC++ と MinGW で DLL とアプリケーションをコンパイルし、それらを混ぜる) を行いました。見たところ、私はより良い結果を得るために
cdecl
の呼び出し規約の方が良い結果でした。
より具体的には:問題点は
stdcall
を使用した場合でも、MSVC++ が DLL エクスポート テーブルの名前を混乱させることです。
extern "C"
. 例えば
foo
は
_foo@4
. この現象は
__declspec(dllexport)
を使用したときだけで、DEF ファイルを使用したときには起こりません。しかし、DEF ファイルはメンテナンスの手間がかかると私は考えており、使用したくありません。
MSVC++ の名前のマングリングは、2 つの問題を引き起こします。
-
使用方法
GetProcAddress
を使用すると、DLLは少し複雑になります。 -
MinGWはデフォルトで、装飾された名前の前にアンデスコアを付けません (例えば、MinGWは、装飾された名前の前に
foo@4
の代わりに_foo@4
の代わりに) を使用すると、リンクが複雑になります。また、アンダースコアのバージョンと互換性のない DLL やアプリケーションが出回る危険性もあります。
私は
cdecl
規約を試してみました。MSVC++ と MinGW の間の相互運用性は完璧に、すぐに機能し、名前は DLL エクスポート テーブルで装飾されないままです。仮想メソッドでさえも機能します。
これらの理由から
cdecl
は私にとって明確な勝者です。
関連
-
[解決済み】C++ クラスヘッダが含まれているときに「不明な型」があるのはなぜですか?重複
-
[解決済み】クラステンプレートの引数リストがない
-
[解決済み】C++でユーザー入力を待つ【重複あり
-
[解決済み】抽象クラス型の無効なnew-expression
-
[解決済み】 while(cin) と while(cin >> num) の違いは何ですか?)
-
[解決済み] Windowsにpipをインストールするにはどうしたらいいですか?
-
[解決済み] Windows での Git リポジトリのディレクトリを無視する
-
[解決済み] Git for Windows でファイル名が長すぎる
-
[解決済み】WindowsでTCPまたはUDPポートをリッスンしているプロセスを見つけるにはどうすればよいですか?
-
[解決済み】共有オブジェクト(.so)、静的ライブラリ(.a)、DLL(.so)の違い?)
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】クラステンプレートの引数リストがない
-
[解決済み】C++でユーザー入力を待つ【重複あり
-
[解決済み】C++のGetlineの問題(オーバーロードされた関数 "getline "のインスタンスがない
-
[解決済み] クラスにデフォルトコンストラクタが存在しない。
-
[解決済み】C++プログラムでのコンソールの一時停止
-
[解決済み】c++でstd::vectorを返すための効率的な方法
-
[解決済み】Visual C++で "Debug Assertion failed "の原因となる行を見つける。
-
[解決済み】エラー:free(): 次のサイズが無効です(fast)。
-
[解決済み】C++ - 適切なデフォルトコンストラクタがない [重複]。
-
[解決済み】演算子のオーバーロード C++; <<操作のパラメータが多すぎる