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

发布于 2025-01-17 10:53:26 字数 181 浏览 3 评论 0原文

我有一个项目“A”,它依赖于“B”。 “B”在启动时动态加载。

想象一下,有一个库“C”满足与“B”相同的接口。使用 B.so 构建的 A.so 可以与 C.so 一起使用而无需重建吗?链接器的工作是找到正确的函数地址吗?

仅通过配置优先考虑 C.so 的 LD_LIBRARY_PATH 就可以“安全”地实现这一点吗?

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 ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

听你说爱我 2025-01-24 10:53:26

编辑:
我似乎误解了这个问题。如果要保持libb.so& libc.so,但使用libc.so作为某些二进制文件,然后将它们保留在单独的文件夹中,然后使ld_librarypath首先找到libc.so文件夹。您将在其中创建一个软链接libc.so-> libb.so。随着环境变量的变化,您可能已经运行需要libc.so的二进制文件。测试它。


让我们定义一个函数str_mod()在两个不同的库中具有相同接口。一个( a )将输入字符串中的所有字符都更改为上案例,而另一个( b )将其逆转。

我们将拥有一个包装器函数库( c str_mod_c()替换字符串本身。后来调用str_mod()

一个调用包装器str_mod_c()的测试程序。当我们替换Core

  1. 创建文件&时会发生什么情况。测试文件夹
test_so/
├── lib_AAA.c
├── lib_BBB.c
├── lib_CCC.c
├── lib_if.h
└── test_so.c
  1. 文件的内容
    • 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:只需将所有字符转换为上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:转换字符串
#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 lib_ccc.c < /code>:用默认字符串test_so.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));
}
  • 中的函数
#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. :调用`lib_ccc.c 编译库 &amp;程序
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. 运行程序

c 替换字符串&amp; 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]
  1. libbbb.so&amp;运行test_ccc_aaa
mv libAAA.so libAAA.so.BAK
ln -s libBBB.so libAAA.so

创建一个软链接libaaa.so-&gt; 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]

OS:Ubuntu 20.04 LTS X64
GCC:9.4

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文