简体   繁体   English

需要重建以将其与提供相同接口的不同库一起使用吗?

[英]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.solibC.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当我们更换核心时会发生什么

  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 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;
}
  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.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]
  1. Replacing libAAA.so with a copy of libBBB.so & run test_CCC_AAAtest_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.

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