![](/img/trans.png)
[英]Can we use same function in 2 different library file , if both the library consumed in same DLL file
[英]Need rebuild to use it with different library that provides the same interface?
我有一个项目“A”依赖于“B”。 “B”在启动时动态加载。
想象一下,有一个库“C”满足与“B”相同的接口。 使用 B.so 构建的 A.so 可以与 C.so 一起使用而无需重建吗? 找到正确的函数地址是链接器的工作吗?
这是否可以通过配置优先级为 C.so 的 LD_LIBRARY_PATH 来“安全地”实现?
编辑:
我似乎误解了这个问题。 如果您想同时保留libB.so
和libC.so
但对某些二进制文件使用libC.so
,则将它们保存在单独的文件夹中,并使 LD_LIBRARYPATH 首先找到libC.so
文件夹。 您将在其中创建软链接libC.so -> libB.so
。 随着环境变量的变化,您可能已经将需要libC.so
的二进制文件与其他二进制文件分开运行。 测试它。
让我们在两个不同的库中定义一个具有相同接口的 function say str_mod()
。 One( A ) 将输入字符串中的所有字符更改为大写,而 other( B ) 将其反转。
我们将有一个包装器 function 库 ( C ) str_mod_C()
来替换字符串本身。 稍后调用str_mod()
。
调用包装器str_mod_C()
的测试程序。 当我们更换核心时会发生什么
test_so/
├── lib_AAA.c
├── lib_BBB.c
├── lib_CCC.c
├── lib_if.h
└── test_so.c
lib_if.h
#ifndef _LIB_IF_H_
#define _LIB_IF_H_ 1
char* str_mod (char* str, size_t slen);
char* str_mod_C (char* str, size_t slen);
#endif
lib_AAA.c
:只将所有字符转换为大写#include <stdio.h>
#include <stddef.h>
#include <ctype.h>
#include "lib_if.h"
// change string to UPPER-CASE
char* str_mod (char* str, size_t slen) {
printf ("\nHello from [%s] = ", __FILE__);
for (size_t ci = 0; ci < slen; ++ci)
str[ci] = toupper (str[ci]);
return str;
}
lib_BBB.c
:反转字符串#include <stdio.h>
#include <stddef.h>
#include <ctype.h>
#include "lib_if.h"
// ESREVER/REVERSE the string in place
char* str_mod (char* str, size_t slen) {
printf ("\nHello from [%s] = ", __FILE__);
for (size_t ai = 0, zi = slen -1; ai < zi; ++ai, --zi) {
char tmp = str[ai];
str[ai] = str[zi];
str[zi] = tmp;
}
return str;
}
lib_CCC.c
:用默认字符串替换字符串#include <stdio.h>
#include <stddef.h>
#include <string.h>
#include "lib_if.h"
// Replaces the string itself!
char* str_mod_C (char* str, size_t slen) {
snprintf (str, slen, "Middle exists just because extremes don't want to meet.");
printf ("Hello from [%s] = [%s]\n", __FILE__, str);
return str_mod (str, strlen(str));
}
test_so.c
:从 `lib_CCC.c 调用 function#include <stdio.h>
#include <string.h>
#include "lib_if.h"
int main () {
char ipStr[] = "DUMA: Power doesn't like to be shared; so, it concentrates.";
printf ("\nOriginal: [%s]\n\n", ipStr);
printf ("Modified: [%s]\n", str_mod_C (ipStr, strlen (ipStr)));
return 0;
}
export LD_LIBRARY_PATH=./:$LD_LIBRARY_PATH
gcc -c -Wall -Wextra -pedantic -g1 -O2 -std=c17 -march=native -fPIC lib_AAA.c
gcc --shared lib_AAA.o -o libAAA.so
gcc -c -Wall -Wextra -pedantic -g1 -O2 -std=c17 -march=native -fPIC lib_BBB.c
gcc --shared lib_BBB.o -o libBBB.so
gcc -c -Wall -Wextra -pedantic -g1 -O2 -std=c17 -march=native -fPIC lib_CCC.c
gcc --shared lib_CCC.o -o libCCC.so
gcc -Wall -Wextra -pedantic -g1 -O2 -std=c17 -march=native test_so.c -L./ -lCCC -lAAA -o test_CCC_AAA
gcc -Wall -Wextra -pedantic -g1 -O2 -std=c17 -march=native test_so.c -L./ -lCCC -lBBB -o test_CCC_BBB
库C替换字符串 & A将其大写。
./test_CCC_AAA
Original: [DUMA: Power doesn't like to be shared; so, it concentrates.]
Hello from [lib_CCC.c] = [Middle exists just because extremes don't want to meet.]
Hello from [lib_AAA.c] = Modified: [MIDDLE EXISTS JUST BECAUSE EXTREMES DON'T WANT TO MEET.]
同样, C替换了字符串,库B将其反转。
./test_CCC_BBB
Original: [DUMA: Power doesn't like to be shared; so, it concentrates.]
Hello from [lib_CCC.c] = [Middle exists just because extremes don't want to meet.]
Hello from [lib_BBB.c] = Modified: [.teem ot tnaw t'nod semertxe esuaceb tsuj stsixe elddiM]
test_CCC_AAA
替换为libAAA.so
的副本并运行libBBB.so
mv libAAA.so libAAA.so.BAK
ln -s libBBB.so libAAA.so
创建了一个软链接libAAA.so -> libBBB.so
ldd test_CCC_AAA
linux-vdso.so.1 (0x00007fffb07e7000)
libCCC.so => ./libCCC.so (0x00007f692dac9000)
libAAA.so => ./libAAA.so (0x00007f692dac4000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f692d8b5000)
/lib64/ld-linux-x86-64.so.2 (0x00007f692dad5000)
test_CCC_AAA
仍然链接到libAAA.so
但执行libBBB.so
的代码
./test_CCC_AAA
Original: [DUMA: Power doesn't like to be shared; so, it concentrates.]
Hello from [lib_CCC.c] = [Middle exists just because extremes don't want to meet.]
Hello from [lib_BBB.c] = Modified: [.teem ot tnaw t'nod semertxe esuaceb tsuj stsixe elddiM]
测试于:
操作系统:Ubuntu 20.04 LTS x64
GCC:9.4
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.