問題タブ [calling-convention]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
visual-c++ - このインターフェイスはMSVCとmingwの間でバイナリ互換ですか?
私は、そのユーザー(同じプロセスに存在する他のライブラリ)がデータバッファーとストリームを交換できるようにするライブラリに取り組んでいます。ライブラリは、MSVCコードとmingwコードの両方から使用できる必要があります(互換性を高めても問題はありませんが、厳密には必要ありません)。これを実現するには、コア機能を小さなコンパイラ互換インターフェイスから提供する必要があります。このインターフェイスは、クライアントコードでコンパイルされるコンビニエンスレイヤーによって後で隠すことができます。
ライブラリの難しい点は、クライアントが独自のバッファとストリームの実装を提供できるように拡張可能である必要があることですが、コアライブラリインターフェイスは、リリースされた後も安定している必要があります。さらに背景に興味がある場合は、フォーラムのスレッドディスカッションでそれについて読むことができます。
コンパイラ間のバイナリ互換性の問題について学ぼうとしましたが、このトピックに慣れていないので、結果についてのコメントに興味があります。私はここで標準で定義された動作には興味がありません(構造体はおそらくそのテストに失敗します)。mingwとMSVC、そして可能であれば他のコンパイラとの互換性にのみ興味があります。
特に、構造体は互換性がありますか?それらは一様に関数ポインタで構成されているので、パディングが問題になることはないと思います。さらに、ここではstdcall規約が必要ですか、それともcdeclも同様に機能しますか?両方のコンパイラがデフォルトでcdeclになるので、指定しないでおくことはできますか?するべきか?これが私が今持っているものです:
編集:これが意図されていたプロジェクトはしばらくの間保留されており、再び棚上げされない場合はおそらく多くの再考が必要です。私はまだ答えに興味があるので、私は質問を残しています。
macos - printf を呼び出す前に %eax がゼロになるのはなぜですか?
x86を少し手に入れようとしています。gcc -S -O0 を使用して 64 ビット Mac でコンパイルしています。
C のコード:
出力:
「printf」が呼び出される前に %eax が 0 にクリアされる理由がわかりません。printf
印刷された文字数を私の最善の推測に戻すため、%eax
準備のためにゼロに設定されますが、準備を整える責任がprintf
あると想定していました。また、対照的に、printf
自分の関数を呼び出すと、準備する必要はありません。では、なぜ扱いが異なるのだろうか。int testproc(int p1)
gcc
%eax
gcc
printf
testproc
windows - Windows x64の呼び出し規約でXMMレジスタを使用して4つを超える整数引数を渡さないのはなぜですか?
(Microsoft)x64呼び出し規約は次のように述べています。
引数は、レジスタRCX、RDX、R8、およびR9で渡されます。引数がfloat/doubleの場合、XMM0L、XMM1L、XMM2L、およびXMM3Lで渡されます。
それは素晴らしいことですが、なぜただフロート/ダブルするのですか?整数(およびおそらくポインター)もXMMレジスターを介して渡されないのはなぜですか?
利用可能なスペースの無駄のように思えますね。
sockets - ソケット使用時の関数呼び出し規則に関するアドバイス
ソケットを使用して、クライアントの 32 ビット アプリケーションと 64 ビット アプリケーションの間で関数呼び出しを行う予定です。
関数を呼び出し、変数を渡し、ソケット インターフェイスを介してパラメーターを返すための最良のスキームは何でしょうか。クライアント コードとサーバー コードの両方を制御できるので、何でも実装できます。
私は、ソケットパケットを以下で構成することを考えていました: - 1 ワード: 関数名の長さ (文字数) - 文字列: 実際の関数名 - 1 ワード: 関数パラメーターの長さ (バイト単位) - 関数パラメーター
最も堅牢で拡張可能なアプローチを教えてください。おそらく、コンパイラ、Web サービス、または仮想マシンによる呼び出し規則で使用される原則を再利用できます。
前もって感謝します
c++ - 関数の引数リスト内での関数呼び出しはスタックを深くしますか?
を呼び出すとF(argument_expression)
、argument_expression
F のスタックをプッシュする前に評価されますか?
たとえば、 を呼び出すときF(G(H(arg)))
、コンパイラは最初に H のスタックをプッシュし、H を評価し、ポップし、次に G のスタックをプッシュしますか? それとも、最初に F のスタックをプッシュし、次に G をプッシュし、次に H をプッシュし、次に 3 つのレイヤーをポップバックしますか?
また、一方の方法はもう一方の方法よりも高速ですか?
c++ - Windows で __cdecl または __stdcall?
私は現在、DLL として配布される Windows 用の C++ ライブラリを開発しています。私の目標は、バイナリの相互運用性を最大化することです。より正確には、DLL の関数は、DLL を再コンパイルすることなく、MSVC++ と MinGW の複数のバージョンでコンパイルされたコードから使用できる必要があります。ただし、どの呼び出し規約が最適か、cdecl
またはstdcall
.
「C の呼び出し規則は、コンパイラ間で同じであることが保証されている唯一の規則です」などのステートメントを時々耳にしcdecl
ます。これは、特定のライブラリ開発者 ( libsndfileなど) が配布する DLL で C 呼び出し規則を使用することを止めるようには見えませんが、目に見える問題はありません。
一方、stdcall
呼び出し規約は明確に定義されているようです。私が聞いたところによると、これは Win32 と COM で使用される規則であるため、すべての Windows コンパイラは基本的にそれに従う必要があります。これは、Win32/COM をサポートしない Windows コンパイラはあまり役に立たないという前提に基づいています。フォーラムに投稿された多くのコード スニペットは関数を として宣言していますが、その理由stdcall
を明確に説明している 1 つの投稿が見つからないようです。
矛盾する情報が多すぎて、検索を実行するたびに異なる答えが得られます。どちらか一方を選択する必要がある理由 (または 2 つが同等である理由) について、明確で詳細な議論のある説明を探しています。
この質問は、「クラシック」関数だけでなく、仮想メンバー関数呼び出しにも適用されることに注意してください。ほとんどのクライアント コードは、純粋な仮想クラスの「インターフェイス」を介して DLL とやり取りするためです (たとえば、 hereおよびthere で説明されているパターンに従います)。
c - C はどのように構造体を返しますか?
ローカル変数を返しているようですt
が、この種の仕事は動作することが保証されており、戻り時にローカル変数を参照しないようになっているのではないでしょうか??
c++ - __cdeclと__declspecの呼び出し規約の混乱
サードパーティアプリケーション用のDLLを作成しています。メインのソフトウェアエンジニアは、アプリケーションが__cdecl(/ Gd)呼び出し規約を使用していると述べています。私はそれを使用することを確認する必要があります。
さらに、サードパーティは、次のように関数をエクスポートするC++DLLスケルトンを提供してくれました。
ちょっと混乱しています。関数が__cdedlではなく__declspec規則を使用してエクスポートされるのはなぜですか?__declspecは_cdeclをサポートしていますか?
ありがとう。
c++ - DLLで__cdeclエクスポート呼び出しと__stdcallインポート呼び出しを混在させることはできますか?
私はサードパーティのアプリケーション用のモジュールを書いています。アプリケーションのuses __cdecl
呼び出し規約。
同時に、私はuses __stdcall
規約を呼び出すレガシーDLLを持っています。
exports __cdecl
一方の端で機能し、もう一方の端で機能するラッパーを作成できますimports __stdcall
か?他にどのようなオプションがありますか?
ありがとう、
編集:
これが私の状況を明確にするのに役立ついくつかの追加情報です。
third_party.exe
にアクセスする必要があるものがありますskeleton.dll
。ソースコードのskeleton.dllには、以下のヘッダーファイルが含まれており、__cdeclを使用してコンパイルされます。
理想的には、スケルトンソースコードを使用してDLLを開発します。残念ながら、現在のVB6レガシーコードをC++に移植するには時間がかかりすぎます。このため、このガイドラインに従ってVB6コードをハックする必要がありました(これは回避策ですが、ActiveXDLLを標準のCDLLとして使用できます)。
私は、変更されたVB6呼び出し規約、またはそれを変更する方法に100%自信がありません。演習では__stdcallを使用しており、私が開発したテストアプリケーションでも問題なく動作するようです。ただし、サードパーティのアプリケーションでテストすると、特定の関数が適切に呼び出されますが、他の関数ではクラッシュします。
アーキテクチャは次のようになります。
レガシーDLLは、dll、lib、およびdefファイルを生成します。ヘッダーファイルがありません。
c - __stdcallの名前の装飾の構文は何ですか?
次のように一連の関数を呼び出すプログラムがあります。
名前の装飾に不一致がある場合、リンカは次のようなエラーを表示します。
私の理解では、_stdcall
構文は'_' + 'name of the function' + '@' + 'number of arguments * 4'
です。
では、なぜリンカーが?VB_Create@@YGHPAD@Z
名前の装飾を求めているのでしょうか。これはどのような基準ですか?