10

疑問に思っていることを検証する必要があります。共有ライブラリ (.dll) が C で記述され、C99 標準を使用し、コンパイラでコンパイルされている場合。MinGwと言います。次に、私の経験では、バイナリ互換性があるため、他のコンパイラから使用できます。MS Visual Studio と言います。私はそれを何度も成功させたので、私の経験で言います。しかし、これが規則であるかどうかを確認する必要があります。

さらに、それが本当にそうであるかどうかを尋ねたいのですが、たとえば openCV のように完全に C で記述されたライブラリが、さまざまな OS ごとにコンパイルされたバイナリを提供しないのはなぜですか? 明らかな理由は、すべてのコンパイル時のパラメーターを設定することであることは知っていますが、それ以外には何もありませんか?

編集:元の論理的な拡張として私が見る追加の質問を追加しています。これは、クローズド ソース ライブラリを作成する方法ではありませんか? ソースを提供するという選択肢はありえないので、バイナリを提供することが唯一の選択肢です。その場合、できるだけ多くのアーキテクチャーにバイナリーを提供することが望ましい結果であり、システムとコンパイラーの間で最高の移植性を得るには C が当然の選択です。右?

4

3 に答える 3

6

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

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

C99 では、関数宣言やシンボル定義での引数の扱い方に特に変更はないと思いますので、ここでも問題はないはずです。

Vijay が言ったように、まだアーキテクチャの違いがあるため、AMD64 ライブラリにリンクするときに x86 ライブラリを使用できないことに注意してください。


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

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

コンパイラ固有のポイント:

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

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

于 2011-07-25T14:21:32.257 に答える
4

一般的なルールは、OS/CPU の組み合わせに標準の ABI があり、その ABI が言語に対して十分に強力である場合、ほとんどのコンパイラはその ABI に従い、結果としてバイナリ互換性があり、ライブラリ (共有またはstatic) 別のコンパイラでコンパイルされたプログラムを、他のコンパイラでコンパイルされたプログラムに問題なく変換できます。

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

この欠如は、C++ が設計されたときに認識されました。C++ が設計された理由です。extern "C"これにより、コンパイラは特定の関数に対して標準 ABI に制限され、ABI が通常サポートしていない追加の C++ 機能がすべて無効になります。

于 2011-07-25T17:10:04.913 に答える
2

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

于 2011-07-25T14:06:17.347 に答える