我可以动态 link 具有重复函数名称的库吗?
Can I dynamically link libraries that have duplicated name of functions?
假设 Library1.so 和 Library2.so 有:
func1(), func2(), glob_data1, glob_data2
情况:
我想在 Library1,
中使用 func1()
和 glob_data1
并在 Library2 中同时使用 func2()
和 glob_data2
。
问题:
当我动态 link 那些库时,我该怎么做?
(C级不行,汇编级有没有办法?)
如果这些符号不打算在库外使用,您可以简单地将它们标记为 __attribute((visibility("hidden")))
(或者更好的是使用 -fvisibility=hidden
编译代码并使用注释 public 函数__attribute((visibility("default")))
).
如果必须保留这些功能 public,您可以 link 您的库带有 -symbolic
标志。这将导致 linker 在可能的情况下解析对本地定义(而不是 PLT 存根)的引用。
请注意 -symbolic
适用于 所有 库符号。可以使用符号别名对符号子集实现相同的效果,但这涉及更多,所以除非您确实需要,否则我不想详细介绍。
Imagine that Library1.so
and Library2.so
has: func1(), func2(), glob_data1, glob_data2
在 Linux(和其他 UNIX 系统)上将两个库加载到单个进程中通常是一个非常糟糕的主意。
当例如library1
中的 func1
调用了 func2
,哪个 func2
被调用了?答案完全取决于库的链接方式、加载方式以及顺序。
如果函数不调用任何其他导出的符号,您可以通过从dlopen
和dlsym
获得的函数指针调用它们:
void *h1 = dlopen("Library1.so", RTLD_LOCAL|RTLD_LAZY);
int (*f1L1)(void) = dlsym(h1, "func1");
void *h2 = dlopen("Library2.so", RTLD_LOCAL|RTLD_LAZY);
int (*f1L2)(void) = dlsym(h2, "func1");
printf("func1 from Library1 returns %d\n", f1L1());
printf("func1 from Library2 returns %d\n", f1L2());
假设 Library1.so 和 Library2.so 有:
func1(), func2(), glob_data1, glob_data2
情况:
我想在 Library1,
中使用 func1()
和 glob_data1
并在 Library2 中同时使用 func2()
和 glob_data2
。
问题:
当我动态 link 那些库时,我该怎么做?
(C级不行,汇编级有没有办法?)
如果这些符号不打算在库外使用,您可以简单地将它们标记为 __attribute((visibility("hidden")))
(或者更好的是使用 -fvisibility=hidden
编译代码并使用注释 public 函数__attribute((visibility("default")))
).
如果必须保留这些功能 public,您可以 link 您的库带有 -symbolic
标志。这将导致 linker 在可能的情况下解析对本地定义(而不是 PLT 存根)的引用。
请注意 -symbolic
适用于 所有 库符号。可以使用符号别名对符号子集实现相同的效果,但这涉及更多,所以除非您确实需要,否则我不想详细介绍。
Imagine that
Library1.so
andLibrary2.so
has:func1(), func2(), glob_data1, glob_data2
在 Linux(和其他 UNIX 系统)上将两个库加载到单个进程中通常是一个非常糟糕的主意。
当例如library1
中的 func1
调用了 func2
,哪个 func2
被调用了?答案完全取决于库的链接方式、加载方式以及顺序。
如果函数不调用任何其他导出的符号,您可以通过从dlopen
和dlsym
获得的函数指针调用它们:
void *h1 = dlopen("Library1.so", RTLD_LOCAL|RTLD_LAZY);
int (*f1L1)(void) = dlsym(h1, "func1");
void *h2 = dlopen("Library2.so", RTLD_LOCAL|RTLD_LAZY);
int (*f1L2)(void) = dlsym(h2, "func1");
printf("func1 from Library1 returns %d\n", f1L1());
printf("func1 from Library2 returns %d\n", f1L2());