4

libsomething私のプロジェクトでは、サードパーティからの静的ライブラリ (これから呼び出される) への依存関係があります。最近、libsomething別のバージョンで利用できるようになりました。私の仕事は、私のソフトウェアに古いバージョンと新しいバージョンのサポートを提供することです。実行時に常に 1 つのバージョンのみlibsomethingが使用されますが、これがどのバージョンであるかは、プログラムの実行間で構成可能である必要があります。

私は WinXP で MSVC2005 を使用しています。二次的な目的は、Linux と GCC に切り替える準備をすることです。

の両方のバージョンがlibsomething同じシンボルを使用しているため、リンク時に両方のバージョンのシンボルが衝突するため、両方を実行可能ファイルにリンクすることは問題外です。

2 つの実行可能ファイル (1 つは古いバージョンにリンクし、もう 1 つは新しいバージョンを使用) を作成できますが、最終的な展開環境でどの実行可能ファイルを呼び出すかを決定することはできません (従来の理由)。

libsomethingの各バージョンの動的ライブラリ ラッパーを作成し、いくつかの構成ファイルに応じて実行時にそれらをリンクするというアイデアを思いつきました。MSCV では、これは 、 などを使用する道を進むことを意味しますがLoadLibrary()GetProcAddress()Linux では および を使用する必要がdlopen()ありdlsym()ます。

libtoolusing (ie, libtldl) が、共有ライブラリを使用するためのこのプラットフォーム依存性をラップしていることを理解しています。これは従うべき適切な道ですか?より良い (または、少なくとも異なる) 方法はありますか? の代替はlibtldlオープンソースとして存在しますか?

4

3 に答える 3

2

dlopen()Linuxでは、共有ライブラリにリンクし、シンボリックリンクを使用してバージョンを修正する方が簡単です。IMOでは、 +を使用するよりもはるかに簡単ですdlsym()

したがって、ライブラリの古いバージョンと新しいバージョンの共有ライブラリを作成します。

g++ -shared -o libshared.so.1.1 -Wl,-soname=libshared.so.1 -L. -Wl,--whole-archive libstatic.a.old -Wl,-no-whole-archive

g++ -shared -o libshared.so.1.2 -Wl,-soname=libshared.so.1 -L. -Wl,--whole-archive libstatic.a.new -Wl,-no-whole-archive

シンボリックリンクを作成します。

ln -s libshared.so.1.1 libshared.so.1
ln -s libshared.so.1 libshared.so

アプリケーションをビルドし、古いバージョンのライブラリにリンクします。どちらのバージョンもバイナリ互換であると思いますが(ABIは壊れていません)、新しいバージョンにはいくつかの新しいシンボルが含まれている可能性があります。

g++ -o myapp myapp.cpp -L. -lshared

共有ライブラリSONAMElibshared.so.1アプリケーションに依存しているため、またはlibshared.so.1からのパスを検索します/etc/ld.so.confLD_LIBRARY_PATH

アプリケーションを実行する前に、またはlibshared.so.1を指すようにシンボリックリンクを設定できます。libshared.so.1.2libshared.so.1.1


ここで使用されるリンカーオプションに関する情報はほとんどありません。

--whole-archive
コマンドラインで--whole-archiveオプションの後に記載されているアーカイブごとに、アーカイブで必要なオブジェクトファイルを検索するのではなく、アーカイブ内のすべてのオブジェクトファイルをリンクに含めます。これは通常、アーカイブファイルを共有ライブラリに変換するために使用され、すべてのオブジェクトが結果の共有ライブラリに含まれるようにします。このオプションは複数回使用できます。
gccからこのオプションを使用する場合の2つの注意事項:まず、gccはこのオプションを認識しないため、-Wl、-whole-archiveを使用する必要があります。次に、アーカイブのリストの後に-Wl、-no-whole-archiveを使用することを忘れないでください。これは、gccが独自のアーカイブのリストをリンクに追加し、このフラグがそれらにも影響を与えないようにするためです。

-soname = name
ELF共有オブジェクトを作成するときは、内部DT_SONAMEフィールドを指定された名前に設定します。実行可能ファイルがDT_SONAMEフィールドを持つ共有オブジェクトにリンクされている場合、実行可能ファイルが実行されると、ダイナミックリンカは、リンカに指定されたファイル名を使用するのではなく、DT_SONAMEフィールドで指定された共有オブジェクトをロードしようとします。

于 2010-05-12T10:05:14.637 に答える
2

どちらを実行するかの決定のために 2 つの実行可能ファイルを使用できないと言ったことは知っていますがexec、構成時に選択されたバージョンに応じて、実行可能ファイルを行き来することはできませんか?

于 2010-05-10T15:09:04.580 に答える