9

具体的には、両方のコンパイラが同じプラットフォーム(OS +命令セット)上にあると仮定します。ただし、オブジェクトファイルの1つは、コンパイラに依存するコードから作成されました。一方、コードはオブジェクト指向であり、カプセル化を尊重します。

私が作っている一種のフレームワークのためにこれが必要です。ターゲットプラットフォームは、GCCおよびJava仮想マシンである任意のシステムです。実際、フレームワークは各プラットフォームでコンパイルされます。フレームワークユーザーを使用するコンパイラーは彼次第です。

4

4 に答える 4

10

それらが同じオブジェクトファイル形式を使用し、同じマシン命令セットを対象としている限り、それらをリンクできるはずです。たとえば、それぞれ独自の言語拡張機能を備えた2つのCコンパイラがあるとします。2つの異なるファイルをコンパイルします。1つはコンパイラAを使用し、もう1つはコンパイラBを使用します。各ソースファイルは、それぞれのコンパイラの言語拡張を使用します。両方のコンパイラが同じプラットフォームとアーキテクチャをターゲットにするように設定されている限り、たとえばLinuxのi386命令セットであれば、ファイルを1つの実行可能ファイルにリンクできるはずです。

wikiのオブジェクトファイル形式のこのリストを参照してください

これもあなたにとって興味深いかもしれません:

オブジェクトファイルを探索するためのUNIXツール

編集

この記事「C++標準ライブラリABI」によると、業界標準のC ++ ABIがあり、この標準に準拠する任意のコンパイラのオブジェクトファイルをリンクできるはずです。あなたはここでその標準を見ることができます:

Itanium C ++ ABI

このドキュメントは、CodeSourcery、Compaq、EDG、HP、IBM、Intel、Red Hat、およびSGIで構成される非公式の業界連合によって共同で作成されました...

このドキュメントでは、C ++プログラムのアプリケーションバイナリインターフェイス、つまり、ユーザーC++コードと実装で提供されるシステムおよびライブラリ間のオブジェクトコードインターフェイスを指定します。これには、事前定義されたデータ型とユーザー定義されたデータ型の両方を含むC ++データオブジェクトのメモリレイアウトと、仮想テーブルなどの内部コンパイラ生成オブジェクトが含まれます。また、関数呼び出しインターフェイス、例外処理インターフェイス、グローバルネーミング、およびさまざまなオブジェクトコード規則も含まれています。

同じ命令セット、オブジェクトファイル形式を対象とし、標準のC ++ ABI(現在はgcc / g ++のデフォルト)を使用している限り、もちろん標準のC ++ ABIが実際に標準であり、適切に実装されていると仮定すると、問題ありません。 Linux上で実行されるほとんどの最新のC++コンパイラー(これは、ターゲットとしているプラ​​ットフォームのようです)。

編集2

このSOの投稿をご覧ください。

APIの下位バイナリ互換性を維持するためのGCCとMSC++コンパイラ

MicrosoftはC++ABIに関して一貫した標準(Itaniumなど)に準拠していないようです。そのため、Windows用のgccを使用してコンパイルすると、問題が発生する可能性があります。

おそらく、次の2つの記事も参照してください。

C++でのポリシー/バイナリ互換性の問題

バイナリ互換性に関するいくつかの考え

ユーザーをItaniumABIをサポートするコンパイラーに制限することもできますが、それはターゲットオーディエンスによって異なります。

于 2011-04-20T09:26:05.900 に答える
7

コンパイラによって異なります。同じABIを使用しているため、相互にリンクできるオブジェクトを生成するものもあれば、そうでないものもあり、オブジェクトをリンクすることもできません。通常、-実際、私は例外を知りません-コンパイラが互換性のないABIを使用している場合、互換性のない名前マングリングも使用しており、リンクフェーズは失敗します。

実際、異なるコンパイラで構築されたオブジェクトをリンクできるようにするには、かなりの労力と協調が必要です。gccの2つの異なるバージョン間でそれがしばしば不可能であった時がありました。

ABIには、名前マングリングよりもはるかに多くのものがあります。

  • オブジェクトの正確なレイアウト(パディング、vtableの形式、RTTI情報の形式などを含む)

  • 例外が実行される方法

  • 結果が返される方法

  • パラメータが渡される方法(レジスタ内かどうか、どのレジスタ、ここでthis

  • 結果/パラメータに使用されないレジスタを保存する人(呼び出し元、呼び出し先、...)

  • テンプレートの処理方法(たとえば、静的データメンバー)

  • 使用される標準ライブラリバージョン

  • ..。

ABIの複雑さを理解するために、Itaniumで使用されるABIを詳細に説明するドキュメントを次に示しますIIRC、これはCABIを説明する同様のドキュメントへの追加です。これは、他のターゲットのgccによって(マシンに依存しないパーツに対して)使用されます。

于 2011-04-20T09:27:14.743 に答える
2

はい。

コンパイルされると、ソースファイルがコンパイラに依存するコードを使用していても、オブジェクトファイルにはコンパイラに依存しない明確に定義されたオブジェクトコードのみが含まれます。

同じオブジェクト形式を使用していることを確認してください。ただし、同じ命令セットが使用されていることはすでにわかっているので、心配する必要はありません。

于 2011-04-20T09:26:07.230 に答える
0

簡単な答えはノーです。2つのオブジェクトファイルは、バイナリ互換である場合にのみリンクできます。(より正確に言えば、それらをリンクできる場合とできない場合がありますが、リンクしても、結果のプログラムは機能しません。)これは、(すべてのタイプのパラメーターに対して)同じ方法でパラメーターを渡すことを意味します。非表示の引数を同じ方法で渡し(たとえば this)、すべてのデータ構造を同じ方法でレイアウトし(vtableなど、表示されないものを含む)、2つのオブジェクトファイルで使用されるすべてのクラスとオブジェクトが同じであること意味。

これはCで機能します。通常、すべてではないにしてもほとんどのプラットフォームがCのバイナリAPIを指定します。C++のバイナリAPIを指定するプラットフォームはほとんどないため、これはC ++ではほとんど機能しません。1つの注目すべき例外はItaniumであり、その仕様です。不完全であるか、尊重されていません。実際には、実際には、同じコンパイラを使用する必要があるだけでなく、同じオプションを使用してコードをコンパイルする必要があります。たとえば、g++とVC++の両方に、とのような2つの異なる互換性のない実装がありstd::vectorます std::string。コンパイラオプション。

于 2011-04-20T11:09:23.913 に答える