8

私は C/C++ プログラマーではなく、Cでのライブラリーのリンケージがどのように機能するかについてほとんど知らないという重要な通知を前置きしたいと思います。

私たちのコードは libstdc++.so.6 (gcc 3.4 だと思います) を使用しています。libstdc++.so.5 (gcc 2.something または 3.2 だと思います) を使用するサードパーティのプリコンパイル済み (クローズド ソース) ライブラリがあります。これはLinux上にあります。サードパーティ製ライブラリの .a バージョンと .so バージョンの両方があります。

サードパーティのライブラリを使用してアプリを構築することは可能ですか? どのように?libstdc++.so.5 をマシンにインストールせずにアプリをビルド/実行することは可能ですか?

重要な情報を忘れてしまった場合は、お知らせください。これに関連する内容がほとんどわかりません。完全な答えはおそらく不可能だと思います。私は本当に方向性とガイダンスを探しています。これを静的にリンクする、それを動的にリンクする、それを再構築する、まあまあを事前に構築する、バージョン x に切り替える、または quizdoodle をシンボリック リンクする、など。

アップデート:

dlopenwithを使用しRTLD_LOCALて、サードパーティのライブラリをアプリの残りの部分から分離しようとしました。これはほとんど機能しているように見えますが、原因不明の大量のメモリ リークが残っています。を呼び出すdlopenと、サード パーティのライブラリがmalloc既に読み込まれている .so.6 などのシンボルを取り込み、混乱が生じるのではないかと考えています。

くすくす笑いながら、サードパーティのライブラリを に入れてみて、LD_PRELOADアプリを実行したところ、メモリ リークが完全になくなったようです。

4

4 に答える 4

7

サードパーティ ライブラリの周りにラッパー ライブラリを構築することを試みることができます。そのライブラリの静的バージョンを使用し、それを静的標準ライブラリ (-static-libgcc - -L を介して適切なバージョンを選択するようにしてください) にリンクします。重要なことは、このラッパー ライブラリを適切に閉じることです。つまり、元のサード パーティ ライブラリのシンボルのみをエクスポートし、それ以外はすべて非表示にする必要があります。このようにして、ラッパー ライブラリはアプリケーションに必要なすべてのシンボルを公開し、標準的なものを内部にカプセル化します。特に、一部のメモリ操作がコードとサードパーティのコードの間で共有されている場合 (たとえば、コードでメモリを割り当て、サードパーティで割り当てを解除する) は、動作が保証されないことに注意してください...そのような場合、唯一のオプションは、このサードパーティを保持することですparty lib を別のプロセス空間に配置します。

まったく同じ問題が発生するため、上記の動的オプションは機能しないと思います-後で。

一般に、同じプロセス空間に異なるランタイムのバイナリを混在させない方がよいでしょう。それはほとんどの場合、災害のレシピです。

于 2009-11-05T17:57:38.267 に答える
4

それほど古くないものを使用する新しいバージョンのライブラリをベンダーに依頼してください。それができない場合は、新しいアプリケーションがまだ古いバージョンのライブラリで動作するかどうかを確認し、必要に応じて元に戻すことができます。同じライブラリの 2 つの異なるバージョンを作成しようとすると、苦痛が伴い、受け入れられる解決策が見つからないと思います。

于 2009-11-02T19:31:14.960 に答える
2

libstdc++.so.6 と libstdc++.so.5 の両方をアプリケーションに同時にリンクするのは簡単ですが、シンボルはどちらかのライブラリから基本的に偶然に取得されるため、その動作はほとんど未定義です。

IMO を成功させる最善の方法は、古いシステム (gcc 3.3 などの互換性のある gcc を使用している) でサードパーティのライブラリを中心に独自のアプリケーションを構築し、IPC を介してメインアプリケーションと通信できるようにすることです (例: 共有)。メモリー)。このまま、いや

ターゲット システムに libstdc++.so.5 を保持したくない場合は、簡単です。gcc の -static フラグを使用して、libstdc++.a をラッパー アプリケーションにリンクします。

于 2009-10-31T19:45:31.317 に答える
1

これまでに示したアプローチの 1 つが機能する可能性がありますが、信頼できる方法でこれを直接行うことはできないと言った方が安全だと思います。完全に C ベースの API (C 互換の構造体、malloc/free によって管理されるメモリなど) を使用してラッパーを作成する場合、pobedim のソリューションを使用できる可能性があります。ただし、C++ 構造を交換する必要がある場合は、リンクを作成できたとしても、同じオブジェクトに対して異なる標準ライブラリの実装が使用されるため、安全ではありません。また、C++ ABI は .5 ベースと .6 ベースのコード ベース間で互換性がない可能性があります (標準ライブラリ sonames に関連して、数年前に Gnu C++ ABI の主要な変更がどのように行われたかはよく覚えていません)。

これを解決するための最も安全な方法は、アプリケーションと問題のライブラリ上に構築されたリソース/コンピューティング サーバー プロセスとの間で何らかの IPC を使用するマルチプロセス アプローチを使用することだと思います。CORBA、D-Bus、Sun RPC、またはパイプやソケットを介したアドホック プロトコルを使用して、ジョブを実行できます。クローズド ソースの 32 ビット コードを 64 ビット アプリで使用しようとしたときにこれを実行しましたが、十分に機能します。パフォーマンスの低下が見られますが、単一のプロセスで C++ ランタイムを混在させようとすることに固有の問題も完全に回避できます。

于 2009-11-07T19:15:24.087 に答える