62

別の(サードパーティの)共有ライブラリにリンクされている共有ライブラリがあります。次に、アプリケーションでdlopenを使用して共有ライブラリをロードします。これはすべて正常に機能します(ファイルが適切なパスにあると仮定します)。

問題は、ライブラリをリンクするときに、サードパーティの共有ライブラリに対してリンクするように指定する必要がないことです。GCCは、未定義の参照に関するエラーを報告せずにそれを受け入れます。だから、質問。未定義の参照についてGCCに通知させるにはどうすればよいですか?

ライブラリを(一時的に)実行可能ファイルに変更すると、未定義の参照が取得されます(ライブラリをリンカに提供していない場合)。(指定すれば問題なく動作します。)

つまり、次のことが行われます。

g++ -fPIC -shared -o libb.so b.o 
g++ -fPIC -shared -o liba.so a.o
g++ -o a.exe a.cpp 

2行目がエラーを出さず、3行目が未定義の参照について不平を言っている場合。

サンプルコード:

ああ:

class a
{
public:
    void foobar();
};

a.cpp:

#include "a.h"
#include "b.h"

void a::foobar()
{
    b myB;
    myB.foobar();
}

int main()
{
    a myA; myA.foobar();
}

bh:

class b
{
public:
    void foobar();
};

b.cpp:

#include "b.h"

void b::foobar()
{
}
4

2 に答える 2

64

-Wl,--no-undefined共有ライブラリを構築するときにリンカーオプションを使用できます。未定義のシンボルはリンカーエラーとして表示されます。

g++ -shared -Wl,-soname,libmylib.so.5 -Wl,--no-undefined \
    -o libmylib.so.1.1 mylib.o -lthirdpartylib
于 2010-03-01T14:19:18.023 に答える
22

さらに調査した後、私はそれらがどのように機能するかを理解しました。共有ライブラリの未定義のシンボルを操作するための2つのリンカーオプションがあります。

最初のものは--no-undefinedです。リンク段階で、すぐに解決されない未解決のシンボルを報告します。手動(-lスイッチを使用)または自動(libgcc_s、C ++ランタイム; libc、Cランタイム; ld-linux-**.so、動的リンカーutils)でリンクされた共有ライブラリでシンボルが見つからない限り、--no-undefinedエラーとして報告されます。それが質問者が必要とした鍵です。

別のキーがあります--no-allow-shlib-undefined(その説明も示唆してい--no-undefinedます)。共有ライブラリをリンクする共有ライブラリの定義が満たされているかどうかを確認します。このトピックに示されているケースでは、このキーはほとんど役に立ちませんが、役立つ場合があります。ただし、それ自体に障害があります。

マンページは、それがデフォルトではない理由についてのいくつかの理論的根拠を提供します。

   --allow-shlib-undefined
   --no-allow-shlib-undefined
       Allows  (the  default)  or  disallows  undefined  symbols  in  shared
       libraries (It is meant, in shared libraries _linked_against_, not the
       one we're creating!--Pavel Shved). This switch is similar to --no-un-
       defined except  that it determines  the  behaviour when the undefined
       symbols are in a shared library rather than a regular object file. It
       does not  affect  how  undefined  symbols in regular object files are
       handled.

       The  reason  that  --allow-shlib-undefined is the default is that the
       shared library being specified at link time may not be  the  same  as
       the one that is available at load time, so the symbols might actually
       be resolvable at load time.  Plus there are some systems,  (eg  BeOS)
       where  undefined  symbols in shared libraries is normal.  (The kernel
       patches them at load time to select which function is most  appropri-
       ate for the current architecture.  This is used for example to dynam-
       ically select an appropriate memset function).  Apparently it is also
       normal for HPPA shared libraries to have undefined symbols.

ld-linux.soたとえば、共有ライブラリの内部ルーチンの一部が動的ローダー(実行可能ファイルと共有ライブラリの両方)に実装されているLinuxシステムの場合、上記の内容も当てはまります。どういうわけかそれをリンクしない限り、あなたはこのようなものを得るでしょう:

/lib64/libc.so.6: undefined reference to `_dl_argv@GLIBC_PRIVATE'
/lib64/libc.so.6: undefined reference to `_rtld_global_ro@GLIBC_PRIVATE'
/usr/lib64/gcc/x86_64-suse-linux/4.3/libstdc++.so: undefined reference to `__tls_get_addr@GLIBC_2.3'
/lib64/libc.so.6: undefined reference to `_rtld_global@GLIBC_PRIVATE'
/lib64/libc.so.6: undefined reference to `__libc_enable_secure@GLIBC_PRIVATE'

これらは、ローダーからの未定義の参照ld-linux.soです。これはプラットフォーム固有です(たとえば、私のシステムでは正しいローダーはです/lib64/ld-linux-x86-64.so)。ローダーをライブラリにリンクして、上記のトリッキーな参照も確認できます。

g++ -fPIC -shared -o liba.so a.o -Wl,--no-allow-shlib-undefined  /lib64/ld-linux-x86-64.so.2
于 2010-03-01T14:23:29.550 に答える