简体   繁体   中英

Need rebuild to use it with different library that provides the same interface?

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

  1. Creating files & test folder :
test_so/
├── lib_AAA.c
├── lib_BBB.c
├── lib_CCC.c
├── lib_if.h
└── test_so.c
  1. Content of the files :
    • 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;
}
  1. Compiling Libraries & Programs
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

  1. Running Programs

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]
  1. Replacing 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM