9

Linux ARM プラットフォームで dlopen を使用して提供された (クローズド ソース) 共有ライブラリ (プラグイン) をロードしようとしています。私はこの方法でロードしようとしています:

void* handle = dlopen(<library_path>/<library_name>, RTLD_NOW);

結果は、次のメッセージで失敗します。

Failed to load <library_path>/<library_name>: undefined symbol: <symbol_name>.

nmでライブラリ内を調べてみましたが、libが剥ぎ取られたようで、シンボルが見つかりませんでした。readelf -s も試してみたところ、実際に次の結果が得られました。

12663: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND <symbol_name>

読んでみると、 readelf -s が参照するライブラリで定義されているシンボルを含むすべてのシンボルが返されることがわかりました。

この質問への答えは私には完全に明確ではありません:これはライブラリにあるはずのシンボルであり、間違った方法でコンパイルされたために存在しないシンボルですか、それとも他の場所で見つけられるはずのシンボルですか? readelf -d の出力は、必要なすべての共有ライブラリを提供していることを示唆しているようです。このエラーは、実行可能ファイルをコンパイルする方法の間違いに関連している可能性がありますか、それともローダーとは関係ありませんか?

また、各列の意味について読みましたが、それらの値はかなり奇妙です。そのシンボルの説明をどのように解釈しますか? アドレスが0なのはなぜですか?タイプが NOTYPE である理由

4

2 に答える 2

6

未定義のシンボル:Xは、ロードされたライブラリの1つからXをエクスポートする必要があることを常に意味しますが、そうではありません。要求されたシンボルがどのライブラリにあるかを調べて、それにリンクする必要があります。

このメッセージは常にライブラリの問題の結果であり、障害ではないことを知っておく必要があります。ライブラリは、すべてのシンボルを取得する方法を知っている必要があります。そうでない場合は、実行可能ファイルを必要なライブラリにリンクできるため、プラグインをロードするときに、要求されたシンボルはすでに認識されています。

このエラーには、より複雑な理由がある可能性があります。プラグインとメインアプリの両方がライブラリにリンクしている場合、リンクしようとすると、とにかく未定義のシンボルで終了する可能性があります。これは、メインアプリとプラグインが異なるバージョンのライブラリを使用している場合に発生する可能性があります(つまり、プラグインは新しいバージョンを使用します)。次に、プラグインをロードする時点で、古いバージョンがすでにロードされているため、ローダーはすべてが正常であると想定しますが、新しいバージョンには新しいシンボルが含まれている可能性があります。プラグインがそれらを使用する場合、未定義のシンボルエラーが発生します。

于 2011-12-03T03:39:10.907 に答える