質問

疑問があるものを確認する必要があります。共有ライブラリ(.DLL)がC99標準を備えたCで記述され、コンパイラの下でコンパイルされている場合。 Mingwを言う。私の経験では、それはバイナリ互換性があり、したがって他のコンパイラから使用可能です。 MS Visual Studioと言います。私はそれを何度もうまく試したので、私の経験で言います。しかし、これがルールであるかどうかを確認する必要があります。

さらに、それが実際にそうであるかどうかを尋ねたいと思います。それから、なぜopencvのようにCで完全に書かれたライブラリが、たとえば、異なるすべてのOSにコンパイルされたバイナリを提供しないのですか?明らかな理由は、すべてのコンパイル時間パラメーターを設定することであることを知っていますが、それ以外は正しいことはありませんか?

編集:オリジナルの論理的な拡張機能と見なされる質問を追加しています。これは、どのようにして閉じたソースライブラリを作成するのではないでしょうか?ソースを与えるオプションはそこに窓から出るので、バイナリを与えることが唯一の選択肢です。そして、その場合、可能な限り多くのアーキテクチャにバイナリを提供することが望ましい結果であり、Cはシステムとコンパイラの間に最高の移植性を持つための明らかな選択肢です。右?

役に立ちましたか?

解決

Windowsの世界におけるCコンパイラ(MSVCおよびGCC/MINGW)の特定のケースでは、バイナリ互換性の仮定が正しいです。 GCCによってコンパイルされたCインターフェイスDLLをVisual Studioのプログラムにリンクできます。これは、FFMPEGのようなC99プロジェクトにより、開発者がVisual Studioのアプリケーションを作成できるようにする方法です。 DLLのMicrosoft ToolchainにあるLib.exeを使用して、Import Libraryを作成する必要があります。または、Mingw.orgのPexports以上を使用して、MingW-W64のGendEFツールを使用して、MINGW-W64のGENDEFツールを使用して、MSVC生成DLLのGCCインポートLIBを作成できます。

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

C99は、機能宣言やシンボルの定義での引数の処理方法に特に変更を変更しないと思います。これもここでも問題はないはずです。

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


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

これはまさに閉じたソースバイナリを作成する方法です。インポートライブラリに加えて、DLLからのエクスポートを隠すことも非常に重要であり、DLL自体をリンクには役に立たないようにすることも非常に重要です(クライアントコードにライブラリでプライベート機能を使用したくない場合は、たとえばの出力を参照してください。 dumpbin /exports Msoffice DLLでは、そこに隠されたものがたくさん)。あなたはGCCで同じことを達成することができます(私はそれを使用したことも試したこともありません) __attribute(hidden) 等...

いくつかのコンパイラ固有のポイント:

  1. MSVCには、 /mt、 /md、および /ldを介して4つの異なるランタイムライブラリを備えた4つの(実際、3つの新しいバージョンには3つのみ)異なるランタイムライブラリが付属しています。これに加えて、互換性を保証するために、Visual Studio(サービスパックを含む)の各バージョンにビルドを提供する必要があります。しかし、それはあなたのための閉じたソースのバイナリとウィンドウです...

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

他のヒント

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

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

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

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top