2011-07-25 27 views
10

疑問があるものを確認する必要があります。共有ライブラリ(.dll)がC言語で記述され、C99標準でコンパイラでコンパイルされている場合。 MinGwと言ってください。その後私の経験ではバイナリ互換性があり、他のコンパイラからは使えます。 MS Visual Studioと言ってください。私は経験を重ねて成功裏に試したので、私の経験で言う。しかし、これがルールであるかどうかを確認する必要があります。クロスコンパイラC言語でのバイナリ互換性

さらに、openCVのように完全にCで書かれたライブラリが、異なるOSごとにコンパイルされたバイナリを提供しないのはなぜですか?私は明らかな理由は、すべてのコンパイル時のパラメータを設定することですが、それ以外の権利はないと知っていますか?

EDIT:私はオリジナルの論理的拡張子として追加の質問を追加しています。これはどうやってクローズドソースライブラリを作成するのでしょうか?ソースを与えるという選択肢がそこから出てくるので、バイナリを与えることが唯一の選択肢です。その場合、可能な限り多くのアーキテクチャ用のバイナリを提供することが望ましい結果であり、Cはシステムとコンパイラ間の移植性を最大限に引き出すための明白な選択です。右?

+0

非常に興味深い質問です。奇妙なことに、私がUN * Xの世界で80年代初頭と中頃にデバッガガイに戻ってきたにもかかわらず、これは深刻な考えを実際に与えたことはありませんでした。もちろん、私は主にシンボルテーブルをガイドとして使用していましたが、構造体のビットパッキングとスタック上のargsのプッシュについての質問が残っています。私はその世界では、ほとんどのコードが製造元のコンパイラまたはGCCのいずれかのバージョンまたは別のバージョンでコンパイルされていると推測しているので、固有の整合性がありましたが、それはあなたが求めているものではありません。 –

答えて

6

Windows環境のCコンパイラ(MSVCおよびGCC/MinGW)の特定のケースでは、バイナリ互換性を前提としています。 Visual StudioでGCCでコンパイルされたCインターフェイスDLLをプログラムにリンクすることができます。これは、ffmpegのようなC99プロジェクトが、開発者がVisual Studioを使ってアプリケーションを書くことを可能にする方法です。 DLLからMicrosoftツールチェーンにあるlib.exeでインポートライブラリを作成するだけで済みます。逆に、mingw.orgのpexports以上のmingw-w64のgendefツールを使用すると、MSVCで生成されたDLL用のGCCインポートライブラリを作成できます。

この便利な相互運用性は、MSVCとGCCのABIが異なり、互換性がないC++インターフェイスワールドに入ると分解されます。それはうまくいくかもしれないし、そうでないかもしれないし、保証がなされておらず、それを変更しようと努力していない(現在)。また、誰かがMSVCのデバッガと互換性のあるGCCにデバッグ情報ジェネレータ/ライタを書き込むまで(もちろんgdbサポートとともに)、デバッグ情報は明らかに異なります。

私はC99が関数宣言や引数がシンボル定義で扱われる方法を特に変更するとは思わないので、ここでも問題はありません。

Vijay氏によれば、アーキテクチャの違いがあるため、AMD64ライブラリにリンクするときにx86ライブラリを使用することはできません。


また、クローズドソースのバイナリについてのあなたの追加質問に答えると、使用可能なすべてのコンパイラ/アーキテクチャのバージョンを配布するには。

これは、クローズドソースバイナリを作成するのとまったく同じです。インポートライブラリに加えて、DLLからのエクスポートを非表示にしてDLL自体をリンクに使用しないようにすることも非常に重要です(クライアントコードでライブラリ内のプライベート関数を使用したくない場合は、例えばdumpbin /exports MSOffice DLLには、たくさんの隠されたものがあります)。あなたは__attribute(hidden)などのものを使ってGCCで同じことを達成することができます。

いくつかのコンパイラの特定のポイント:

  1. MSVCは/ MT、/ MDを通じて4(新しいバージョンで、残りも、実際にはわずか3)異なるランタイムライブラリが付属しており、/ LD。さらに、互換性を保証するために、Visual Studioの各バージョン(Service Packを含む)のビルドを提供する必要があります。しかし、それはあなたのためのクローズドソースバイナリとWindowsです...

  2. GCCにはこの問題はありません。 MinGWは、Windows(Windows 98以降)から提供されるmsvcrt.dllにリンクします。これは/ MDと同等です(そして/ MDdと同等のデバッグライブラリでもあります)。しかし、バイナリ互換性を保証しないMinGW(mingw.orgとmingw-w64)の2つのバージョンがあります。後者は、64ビットオプションと32ビットを提供し、より完全なヘッダ/ライブラリセット(DirectXとDDKのかなりの部分を含む)を提供するので、より完全です。

+0

答えをくれてありがとう、もちろん、別のアーキテクチャーは他のコンパイラーと再コンパイルする必要があります。 C++インターフェイスの意味は?すべてのコンパイラで、外部ライブラリのCコードを呼び出すことができるのと同じではありませんか? extern "C" {...}? 私の質問は、クローズドソースライブラリの開発方法にも及んでいます。あなたはバイナリだけを提供する必要があるでしょう。そうすれば、最高のバイナリ・ポータビリティが明白な選択となるでしょうか? – Lefteris

+0

Lefteris:私の更新を見てください。そうですね、 'extern" C "{...}"はCインタフェースを提供するために必要なものです。 g ++でコンパイルして、クロスコンパイラとの互換性のためのショーストッパーの1つである名前の変更を可能にする部分を除いて、C++インターフェイスを作成することができます。 – rubenvb

+0

本当にありがとうございました。かなり詳細でした。私が知っている名前のmanglingに関しては、残念なことに過去に何度も私の顔にそれを持っていて、これは私のプロジェクトのいくつかの移植性のためにCに戻ってきたものです。 – Lefteris

2

特定のアーキテクチャにコンパイルされた共有ライブラリまたはDLLは、同じアーキテクチャを対象とする他のコンパイラによってコンパイルされたアプリケーションにリンクできます。 (アーキテクチャによって、私はプロセッサー/ OSの組み合わせを意味する)。しかし、ライブラリ開発者がすべての可能なアーキテクチャに対してコンパイルすることは現実的ではありません。さらに、ライブラリがソース形式で配布される場合、ユーザーは特定の要件に合わせて最適化されたバイナリを構築できます。

4

一般的なルールは、あなたのOS/CPUの組み合わせが標準ABIを持っている場合、そのABIは、あなたの言語のために十分に強力である場合には、ほとんどのコンパイラは、ABI、結果としては、できるように、バイナリ互換性があることに従うということです異なるコンパイラでコンパイルされたライブラリ(共有または静的)を他のコンパイラでコンパイルされたプログラムにリンクするだけです。

問題は、ほとんどのABIはCやFORTRANのような低レベルの言語を中心に設計されており、C++のようなオブジェクト指向言語より前の日付にまでさかのぼります。したがって、関数のオーバーロード、ユーザー定義の演算子、例外、グローバルコンストラクタとデストラクタ、仮想関数、継承などC++で必要とされるもののサポートが不足する傾向があります。

C++が設計されているためにC++にextern "C"があると認識されていましたが、コンパイラはABIが標準でサポートしていない機能をすべて無効にします。

関連する問題