7

我正在使用 dlopen 在运行时加载共享库

dlopen("SharedLibarary1.so", RTLD_NOW | RTLD_GLOBAL);

在该共享对象中,我指的是在另一个共享库“SharedLibarary2.so”中定义的 const char*。

可执行文件和两个库都是使用 -rdynamic 构建的。

但是在使用 dlopen 时我仍然会遇到运行时错误:“/usr/lib/SharedLibarary1.so: undefined symbol”并指向损坏的 const char* 具有未定义的符号。

通过 GDB“信息共享”,我可以看到第二个库在出现错误时没有加载。

如果我在第一个库上执行 dlopen 之前在第二个库上执行该问题,那么这个问题会如何消失。

有没有更好的方法来强制加载器为未解析的符号加载第二个库?

4

2 回答 2

8

构建共享库时,您可以在内部链接另一个,例如

 gcc -shared -rdynamic lib1*.pic.o -lshared2 -o SharedLibrary1.so  

然后检查ldd SharedLibrary1.so

(例如,以ldd系统的输出libgtk-3.so.0为例)

% ldd /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
linux-vdso.so.1 =>  (0x00007fff6afff000)
libgdk-3.so.0 => /usr/lib/x86_64-linux-gnu/libgdk-3.so.0 (0x00007f0572628000)
libgmodule-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgmodule-2.0.so.0 (0x00007f0572424000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f057221b000)
libpangocairo-1.0.so.0 => /usr/lib/x86_64-linux-gnu/libpangocairo-1.0.so.0 (0x00007f057200e000)
libX11.so.6 => /usr/lib/x86_64-linux-gnu/libX11.so.6 (0x00007f0571cd2000)
libXi.so.6 => /usr/lib/x86_64-linux-gnu/libXi.so.6 (0x00007f0571ac2000)
libXcomposite.so.1 => /usr/lib/x86_64-linux-gnu/libXcomposite.so.1 (0x00007f05718c0000)
libXdamage.so.1 => /usr/lib/x86_64-linux-gnu/libXdamage.so.1 (0x00007f05716be000)
libXfixes.so.3 => /usr/lib/x86_64-linux-gnu/libXfixes.so.3 (0x00007f05714b7000)
libatk-1.0.so.0 => /usr/lib/x86_64-linux-gnu/libatk-1.0.so.0 (0x00007f0571294000)
libcairo-gobject.so.2 => /usr/lib/x86_64-linux-gnu/libcairo-gobject.so.2 (0x00007f057108b000)
libcairo.so.2 => /usr/lib/x86_64-linux-gnu/libcairo.so.2 (0x00007f0570d91000)
libgdk_pixbuf-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgdk_pixbuf-2.0.so.0 (0x00007f0570b71000)
libpangoft2-1.0.so.0 => /usr/lib/x86_64-linux-gnu/libpangoft2-1.0.so.0 (0x00007f0570946000)
libpango-1.0.so.0 => /usr/lib/x86_64-linux-gnu/libpango-1.0.so.0 (0x00007f05706f8000)
libfreetype.so.6 => /usr/lib/x86_64-linux-gnu/libfreetype.so.6 (0x00007f0570459000)
libfontconfig.so.1 => /usr/lib/x86_64-linux-gnu/libfontconfig.so.1 (0x00007f0570222000)
libgio-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0 (0x00007f056fece000)
libgobject-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0 (0x00007f056fc7e000)
libglib-2.0.so.0 => /lib/x86_64-linux-gnu/libglib-2.0.so.0 (0x00007f056f986000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f056f703000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f056f4e7000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f056f160000)
libXext.so.6 => /usr/lib/x86_64-linux-gnu/libXext.so.6 (0x00007f056ef4c000)
libXinerama.so.1 => /usr/lib/x86_64-linux-gnu/libXinerama.so.1 (0x00007f056ed4a000)
libXrandr.so.2 => /usr/lib/x86_64-linux-gnu/libXrandr.so.2 (0x00007f056eb42000)
libXcursor.so.1 => /usr/lib/x86_64-linux-gnu/libXcursor.so.1 (0x00007f056e937000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f056e733000)
/lib64/ld-linux-x86-64.so.2 (0x00007f0572f57000)
libxcb.so.1 => /usr/lib/x86_64-linux-gnu/libxcb.so.1 (0x00007f056e512000)
libpixman-1.so.0 => /usr/lib/x86_64-linux-gnu/libpixman-1.so.0 (0x00007f056e28c000)
libpng12.so.0 => /lib/x86_64-linux-gnu/libpng12.so.0 (0x00007f056e064000)
libxcb-shm.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-shm.so.0 (0x00007f056de61000)
libxcb-render.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-render.so.0 (0x00007f056dc57000)
libXrender.so.1 => /usr/lib/x86_64-linux-gnu/libXrender.so.1 (0x00007f056da4d000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f056d836000)
libexpat.so.1 => /lib/x86_64-linux-gnu/libexpat.so.1 (0x00007f056d60b000)
libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007f056d3eb000)
libresolv.so.2 => /lib/x86_64-linux-gnu/libresolv.so.2 (0x00007f056d1d5000)
libgthread-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgthread-2.0.so.0 (0x00007f056cfd2000)
libffi.so.5 => /usr/lib/x86_64-linux-gnu/libffi.so.5 (0x00007f056cdc5000)
libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007f056cb87000)
libXau.so.6 => /usr/lib/x86_64-linux-gnu/libXau.so.6 (0x00007f056c983000)
libXdmcp.so.6 => /usr/lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007f056c77e000)
于 2012-10-19T14:37:04.147 回答
2

如果可能,您应该将 dlopen() 的每个共享库与链接器参数链接,以强制它在创建库时解析所有符号。通过这种方式,您可以更加确定您知道所有符号的来源。(例如,“-z defs”,在 Linux x86 下)

这样,如果您添加了一个新的源文件,但忘记将对象添加到链接中,您将不会因为 dlopen/dlsym 的运行时错误而摸不着头脑。

于 2012-11-01T20:15:34.440 回答