[英]Need rebuild to use it with different library that provides the same interface?
I have a project "A" that has dependency to "B".我有一个项目“A”依赖于“B”。 "B" is dynamically loaded in start up time.
“B”在启动时动态加载。
Imagine there's a library "C" that satisfies the same interface as "B".想象一下,有一个库“C”满足与“B”相同的接口。 Can A.so that is built using B.so be used with C.so without rebuild?
使用 B.so 构建的 A.so 可以与 C.so 一起使用而无需重建吗? Is it linker's job to find the correct function's addresses?
找到正确的函数地址是链接器的工作吗?
Can this be "safely" achieved just by configuring LD_LIBRARY_PATH that prioritizes C.so?这是否可以通过配置优先级为 C.so 的 LD_LIBRARY_PATH 来“安全地”实现?
Edit:编辑:
I seem to have misunderstood the question.我似乎误解了这个问题。 If you want to keep both
libB.so
& libC.so
but use libC.so
for some binaries, then keep them in separate folders and make LD_LIBRARYPATH to find libC.so
folder first.如果您想同时保留
libB.so
和libC.so
但对某些二进制文件使用libC.so
,则将它们保存在单独的文件夹中,并使 LD_LIBRARYPATH 首先找到libC.so
文件夹。 Where you'll create a soft-link libC.so -> libB.so
.您将在其中创建软链接
libC.so -> libB.so
。 You may have run the binary that needs libC.so
separately than others, as the environment variables change.随着环境变量的变化,您可能已经将需要
libC.so
的二进制文件与其他二进制文件分开运行。 Test it.测试它。
Let's define a function say str_mod()
with same interface in two different library.让我们在两个不同的库中定义一个具有相同接口的 function say
str_mod()
。 One( A ) changes all characters in input string to upper-case, while other( B ) reverses it. One( A ) 将输入字符串中的所有字符更改为大写,而 other( B ) 将其反转。
We'll have a wrapper function library( C ) str_mod_C()
which replaces the string itself.我们将有一个包装器 function 库 ( C )
str_mod_C()
来替换字符串本身。 Later calls str_mod()
.稍后调用
str_mod()
。
A test program which calls the wrapper str_mod_C()
.调用包装器
str_mod_C()
的测试程序。 What happens when we replace the core当我们更换核心时会发生什么
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
: Just converts all chars to upper-case 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
: reverses the string 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
: replaces the string with a default string 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
: calls a function from `lib_CCC.c 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
Library C replaces the string & A capitalises it.库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.]
Again, C replaces the string, library B reverses it.同样, 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]
libAAA.so
with a copy of libBBB.so
& run test_CCC_AAA
test_CCC_AAA
替换为libAAA.so
的副本并运行libBBB.so
mv libAAA.so libAAA.so.BAK
ln -s libBBB.so libAAA.so
Created a soft-link libAAA.so -> libBBB.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
is still linked to libAAA.so
but executes libBBB.so
's code 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]
Tested on:测试于:
OS: Ubuntu 20.04 LTS x64操作系统:Ubuntu 20.04 LTS x64
GCC: 9.4 GCC:9.4
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.