私はMac OS X(10.8.2)のC++で作業しており、最近、libc ++ stdlibを使用するclang ++コンパイラーで利用可能なC++ 11機能を使用する必要性を思いつきました。ただし、libstdc ++(MacPortsから提供)に対してコンパイルおよびリンクされたレガシーライブラリを使用する必要もあります。
そうすることで、std::string
(つまり、std::__1::basic_string
のlibc ++実装)に対して解決する必要があるstd::string
などを使用するレガシーライブラリのヘッダーのため、リンクエラーが発生しました。 std::basic_string
実装の代わりに。
開発中の2つのライブラリを混在させる方法はありますか(たとえば、いくつかのプリプロセッサフラグを使用して)?
表示されているのは、インライン名前空間を使用してABIバージョン管理を実現することです。
その意味:
Libstdc ++ std::string
は、libc ++ std::string
とは異なるデータ構造です。前者は参照カウント設計ですが、後者はそうではありません。 API互換ですが、ABI互換ではありません。つまり、std::string
をlibstdc ++で作成し、それをlibc ++に対してリンクされている他のコードに渡すと、受信コードはlibc ++ std::string
を持っていると見なします。つまり受信者は、参照カウントをインクリメントまたはデクリメントする必要があるという手掛かりを持ちません。
インライン名前空間がないと、結果は実行時エラーになります。期待できる最高のものはクラッシュです。インライン名前空間では、この実行時エラーはリンク時エラーに変換されます。
プログラマにとって、libstdc ++ std::string
とlibc ++ std::string
は同じ型のように見えます。しかし、リンカにとっては、それらはまったく異なる型のように見えます(手がかりはstd::__1
名前空間です)。そして、リンカーのビューは正しいです。 are完全に異なるタイプ。
そのため、いくつかのプリプロセッサフラグを操作して、リンクさせることができます。しかし、その場合、結果の実行時バグをデバッグするという悪魔になります。
あなたがしたいことをする唯一の方法は、これらのdylib間のインターフェースにstring
などのstd::
型を含まないようにすることです。たとえば、代わりにchar
の配列を渡すことができます。メモリの所有権をlibstdc ++にリンクされたコードからlibc ++にリンクされたコードに、またはその逆に転送することもできます(両方が同じmallocプールにドロップスルーします)。