0

私は周りを見回して最善を尽くしましたが、これを解決することはできません:

libmergestream.so など、ユーザーが作成した共有オブジェクトを動的にロードするアプリケーションをコンパイルしています。

mergestream.cpp (libmergestream.so の派生元) には、CImg ライブラリ呼び出しが含まれています。共有オブジェクトを-lpthread -lX11 -lXext -lXrandrフラグ付きでコンパイルします。

次に、アプリケーションの 2 番目の部分を実行可能ファイルとしてビルドし-L/usr/lib/x86_64-linux-gnu、リンカー フラグを介して同じフラグとライブラリを提供します。

アプリケーションを実行すると、共有オブジェクトのロードが失敗し、次のメッセージが表示されます。

Sun Jun  3 19:35:24 2012[1,6]<stdout>:0x7f46705e4180 ../DALProcesses/lib/libmergestream.so: undefined symbol: XUnlockDisplay

何も欠けていないことを確認するために、小さな CImg ライブラリの例を取り上げ、それを実行可能ファイル (共有オブジェクトなし) にビルドしました。それはうまくいきます。ここでは参考までに、これを CImgExample バイナリと呼びます。

CImgExample バイナリでシンボルを検索します。

nm CImgExample | grep 'XUn'
         U XUngrabKeyboard
         U XUnlockDisplay
         U XUnmapWindow

バイナリ自体には未定義のシンボルがありますが、それでも実行できます。

CImgExample の ldd の場合:

linux-vdso.so.1 =>  (0x00007fff988f5000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f4f08e61000)
libX11.so.6 => /usr/lib/x86_64-linux-gnu/libX11.so.6 (0x00007f4f08b2d000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f4f0882c000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f4f08532000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f4f0831c000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f4f07f5e000)
/lib64/ld-linux-x86-64.so.2 (0x00007f4f090ab000)
libxcb.so.1 => /usr/lib/x86_64-linux-gnu/libxcb.so.1 (0x00007f4f07d40000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f4f07b3c000)
libXau.so.6 => /usr/lib/x86_64-linux-gnu/libXau.so.6 (0x00007f4f07938000)
libXdmcp.so.6 => /usr/lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007f4f07732000)

比較のために、libmergestream.so の nm 出力を次に示します。

nm libmergestream.so | grep 'XUn'
                 U XUngrabKeyboard
                 U XUnlockDisplay
                 U XUnmapWindow

libmergestream.so を動的にロードするアプリケーション (「メイン」と呼びます) の ldd は次のとおりです。

linux-vdso.so.1 =>  (0x00007fff8dfff000)
libmpi.so.1 => not found
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fa79c69a000)
libmpi_cxx.so.1 => not found
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fa79c495000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fa79c195000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fa79bf7e000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa79bbc1000)
/lib64/ld-linux-x86-64.so.2 (0x00007fa79c8e4000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fa79b8c7000)

次の 2 つのライブラリ参照が「メイン」にないことに気付きました。

libXau.so.6 => /usr/lib/x86_64-linux-gnu/libXau.so.6 (0x00007f4f07938000)
libXdmcp.so.6 => /usr/lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007f4f07732000)

おもしろいことに、Linux サーバーで共有ライブラリと「メイン」の両方に対して同じビルド プロセスを実行したところ、すべてうまくいきました。何かが嫌いなのが私のノートで、何がなんだかわからない。

4

2 に答える 2

2

また、ライブラリに CImg の表示機能が必要ない場合は、X11 の使用を無効にすることができます。

#define cimg_display 0

「CImg.h」ファイルのインクルードの直前。

于 2012-06-07T09:09:05.707 に答える
1

あなたは言いませんが、Linuxでgccを使用しているようです。その場合は、ld に --no-undefined フラグを指定して libmergestream.so をビルドしてみてください (コンパイラ ドライバ経由で渡している場合は、-Wl,--no-undefined を使用してください)。未定義のシンボルを満たすために必要なすべてのライブラリがリンク行で提供されていない限り、これは libmergestream.so のリンクに失敗します。おそらく、同じシンボルに関する苦情でリンクが失敗することに気付くでしょう。リンクが成功するまで、必要なライブラリを libmergestream.so のライブラリ リストに追加できるようになりました。これらの新しい依存関係は、ライブラリの「必要な」セットに追加され、実行時に一緒にロードされます。

libmergestream.so に、ロードする実行可能ファイル自体によって満たされることが期待されるシンボルがない限り、これは機能するはずです (その場合は --export-dynamic でコンパイルする必要があります)。その場合、おそらく --no-undefined を使用して完全なリンクに到達することはできませんが、これを使用して、まだ追加する必要があるライブラリを見つけることができます:リンクに失敗すると、実行可能ファイルによって提供されるリンクが表示されます。 --no-undefined を削除すると、その時点で問題ありません。しかし、実行可能ファイルに依存するよりも、そのサポートを別の共有ライブラリに抽象化する方が実際には優れています。実行時にロードする予定のライブラリには、可能な限り --no-undefined を使用する必要があります。

于 2012-06-05T15:54:33.633 に答える