共享库与依赖关系的动态链接

时间:2021-05-22 05:34:39

Is there a way to dynamically link shared libraries that have dependencies?

有没有办法动态链接具有依赖项的共享库?

For example, I have two libraries, libA.so and libB.so. libB.so calls functions defined in libA.so.

例如,我有两个库,libA.so和libB.so. libB.so调用libA.so中定义的函数。

In my main program, I wish to load the two libraries with dlopen. However, if I try:

在我的主程序中,我希望用dlopen加载这两个库。但是,如果我尝试:

dlopen(libA.so);
dlopen(libB.so);

Then the second dlopen will fail as libB has unrecognized symbols.

然后第二个dlopen将失败,因为libB具有无法识别的符号。

I can think of a few workarounds such as building all the object files into a single shared library, or to have libB.so call dlopen on libA.so, but that's extra work.

我可以想到一些解决方法,例如将所有目标文件构建到单个共享库中,或者让libB.so在libA.so上调用dlopen,但这是额外的工作。

I guess the way I'm imagining this to work is like in the case of kernel modules where you can use "EXPORT_SYMBOL()" to allow other modules to call functions defined in a previously loaded module.

我想我想象这个工作的方式就像内核模块一样,你可以使用“EXPORT_SYMBOL()”来允许其他模块调用先前加载的模块中定义的函数。

Can something similar be done with shared libraries? Or will I have to use my workarounds?

可以使用共享库完成类似的操作吗?或者我必须使用我的解决方法吗?

2 个解决方案

#1


2  

I experienced a similar situation, this is what worked for me (using a gcc toolchain):

我遇到了类似的情况,这对我有用(使用gcc工具链):

When you create the shared object libB.so, you unconditionally link the library libA.so, the command should look like this:

当您创建共享对象libB.so时,无条件地链接库libA.so,该命令应如下所示:

gcc -shared -Wl,--no-as-needed -lA -o libB.so b.o

You can then check that libA.so indeed became a dependency for the dynamic linker:

然后,您可以检查libA.so是否确实成为动态链接器的依赖项:

$ ldd libB.so
    linux-gate.so.1 =>  (0xb77ba000)
    libA.so => not found
    libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb75f7000)
    /lib/ld-linux.so.2 (0xb77bb000)

In your main program it should be sufficient to only dlopen() the library libB.so, and the other library should get linked automatically by the dynamic linker.

在你的主程序中,只有dlopen()库libB.so就足够了,而另一个库应该由动态链接器自动链接。

#2


1  

Have you tried using RTLD_GLOBAL?

您是否尝试过使用RTLD_GLOBAL?

RTLD_GLOBAL The symbols defined by this library will be made available for symbol resolution of subsequently loaded libraries.

RTLD_GLOBAL此库定义的符号将可用于后续加载的库的符号解析。

This should work fine even if B depends on A:

即使B依赖于A,这应该可以正常工作:

void * const handleA = dlopen("libA.so", RTLD_NOW | RTLD_GLOBAL);
void * const handleB = dlopen("libB.so", RTLD_NOW);

#1


2  

I experienced a similar situation, this is what worked for me (using a gcc toolchain):

我遇到了类似的情况,这对我有用(使用gcc工具链):

When you create the shared object libB.so, you unconditionally link the library libA.so, the command should look like this:

当您创建共享对象libB.so时,无条件地链接库libA.so,该命令应如下所示:

gcc -shared -Wl,--no-as-needed -lA -o libB.so b.o

You can then check that libA.so indeed became a dependency for the dynamic linker:

然后,您可以检查libA.so是否确实成为动态链接器的依赖项:

$ ldd libB.so
    linux-gate.so.1 =>  (0xb77ba000)
    libA.so => not found
    libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb75f7000)
    /lib/ld-linux.so.2 (0xb77bb000)

In your main program it should be sufficient to only dlopen() the library libB.so, and the other library should get linked automatically by the dynamic linker.

在你的主程序中,只有dlopen()库libB.so就足够了,而另一个库应该由动态链接器自动链接。

#2


1  

Have you tried using RTLD_GLOBAL?

您是否尝试过使用RTLD_GLOBAL?

RTLD_GLOBAL The symbols defined by this library will be made available for symbol resolution of subsequently loaded libraries.

RTLD_GLOBAL此库定义的符号将可用于后续加载的库的符号解析。

This should work fine even if B depends on A:

即使B依赖于A,这应该可以正常工作:

void * const handleA = dlopen("libA.so", RTLD_NOW | RTLD_GLOBAL);
void * const handleB = dlopen("libB.so", RTLD_NOW);