2012-04-24 13 views
9

たとえば、共有ライブラリに対応する次のヘッダーファイルを想定します。共有ライブラリは、1つのコンパイラを使用して構築され、それが異なるためで動作しない可能性があり、別のコンパイラで構築されたCコードから使用されている場合C構造体の整列とコンパイラ間の移植性

// lib.h 

typedef struct { 
    char c; 
    double d; 
    int i; 
} A; 

DLL_EXPORT void f(A* p); 

:エクスポートされた関数は、このヘッダに定義されたカスタム構造体へのポインタを取りメモリアライメントは、Memory alignment in C-structsが示唆しているとおりです。だから、私の構造体定義を同じプラットフォーム上の異なるコンパイラ間で移植可能にする方法はありますか?

私は特にWindowsプラットフォームに興味があります(明らかにABIは明確に定義されていません)が、他のプラットフォームについても知りたいと思うでしょう。

+3

いいえ、誰かがそれを保証しない限り。 –

+3

重複はありません。少なくとも選択された質問のうちではありません。これは単独で立つことができます。 –

+1

"struct alignment"という単語を含む質問は、それが何もしなくても自動的に他の質問と重複していますか? –

答えて

11

TL;実際にはDRはうまくいくはずです。

C標準ではこれを定義していませんが、プラットフォームABIは一般的にそういったことをしています。つまり、特定のCPUアーキテクチャとオペレーティングシステムでは、Cがどのようにアセンブリにマップされ、異なるコンパイラが相互運用できるようにするかという定義があります。

プラットフォームのABIが定義しなければならないのは構造体の整列だけではなく、関数呼び出し規約やそのようなものもあります。 Windowsでは

C++は、それがさらに複雑になり、ABIは、vtableをを指定する必要があり、例外は、名前の符号化、など私は、複数のC++ ABIのは、コンパイラによってはあると思いますが、Cは、コンパイラ間でほとんど互換性があります。私はWindowsの専門家ではなく、間違っている可能性があります。

いくつかのリンク:

にどのように進化したかC++ ABI issues list

  • 例C++ ABI仕様http://sourcery.mentor.com/public/cxx-abi/abi.html
  • を定義する必要がありhttp://gcc.gnu.org/ml/libstdc++/2001-11/msg00063.html
  • ものプラットフォーム/コンパイラABI仕様であり、C標準ではありません。

  • +0

    私の質問はC++にはまったく関係しませんが、あなたの努力に感謝します。私はABIについても知っています。なぜなら、Windows上のABI仕様について聞いたことがないので、私はWindows固有の質問に印を付けました。 –

    +0

    @ 7vies:CにはABIもあります(さまざまな呼び出し規約、cdecl、stdcall、fastcallを考えてください)。 Cのために、OSがシステムコールに期待するものと一致する以外の理由がない場合、異なるコンパイラは通常(少なくとも「通常の」呼び出し規約では)同じです。 C++では、さまざまなコンパイラが同じAPI、特に外部の名前に同意しないことが多いです。 –

    +0

    @MichaelBurrは、サイドノートとして、これらは_x86_の規約であり、他のアーキテクチャでも使用されていると言いますか?私はC++の問題を認識しているので、純粋なC言語で動作させる方法を尋ねています。呼び出し規約はポータブルインターフェイスを定義するのに役立ちますが、構造の整列に関する問題を解決しません。 –

    1

    同じコンパイラを使用しても、ビルドで使用される異なるコンパイラスイッチや、同じコンパイラと同じスイッチの異なるバージョンを使用すると違いが生じることがあります私が取り組んだ組み込みコンパイラ)。

    コンパイラがあなたに与えたものであれば、構造体が全く同じであることを確認し、スイッチ、#pragmaを使用する必要があります。

    私のアドバイス - このことからすべての道を離れること。構造体内にラップされていない関数に引数を渡します。

    この単純な形式でも、2つのコンパイラを扱うと、それほど簡単なことではありません。たとえば、intのバイト数が同じであることを確認する必要があります。また、引数を左から右に、または右から左へと呼び出すことも、コンパイラによって異なる場合があります。

    3

    確実に知る唯一の方法は、該当するコンパイラのドキュメントを参照することです。しかし、通常、Cの構造体レイアウト(あなたが言うように、ビットフィールドの場合を除く)は使用する環境のABI記述によって定義され、CコンパイラはネイティブのABIに従う傾向があります。