I have a project "A" that has dependency to "B". "B" is dynamically loaded in start up time.
Imagine there's a library "C" that satisfies the same interface as "B". Can A.so that is built using B.so be used with C.so without rebuild? 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?
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. Where you'll create a soft-link libC.so -> libB.so
. You may have run the binary that needs libC.so
separately than others, as the environment variables change. Test it.
Let's define a function say str_mod()
with same interface in two different library. One( A ) changes all characters in input string to upper-case, while other( B ) reverses it.
We'll have a wrapper function library( C ) str_mod_C()
which replaces the string itself. Later calls str_mod()
.
A test program which calls the wrapper 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 #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 #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 #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 #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.
./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.
./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
mv libAAA.so libAAA.so.BAK
ln -s libBBB.so libAAA.so
Created a soft-link 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
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
GCC: 9.4
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.