我有以下顺序
可执行文件(主要)----(dlopen)---> libapp.so ---(动态链接) - > libfoo.so
libfoo.so依次动态链接到libfoo_strong.so。 libfoo.so从中调用函数 libfoo_strong.so,但也有一个弱定义(在foo.c中编译成libfoo.so)。
现在,libapp.so从libfoo.so调用一个函数(比如invoke_foo_func_ptr(),这个函数>调用一个函数指针,存储定义为弱的符号。我的期望是> invokes_foo_func_ptr调用强符号,但它始终是弱符号。请参阅下面的>代码了解详细信息。
PS:不要让我解释特定执行顺序的原因,但我愿意接受> workarounds。
foo_strong.c - > gcc -g -fPIC -shared -rdynamic foo_strong.o -o libfoo_strong.so
foo.c: - > gcc -g -fPIC -shared -rdynamic -L / users / ardesiga / cprogs / ld_r foo.o -o libfoo.so
app.c: - > gcc -g -fPIC -shared -rdynamic -L / users / ardesiga / cprogs / ld_r -lfoo -lfoo_strong app.o -o>的 libapp.so
/* foo_strong.c */
int
foo_weak_func (char *msg)
{
printf("[%s:%s] Reached strong, with msg: %s\n", __FILE__, __FUNCTION__, msg);
}
/* foo.c */
#include <stdio.h>
#include <stdlib.h>
#include "foo_ext.h"
#include "foo_weak.h"
int __attribute__ ((weak)) foo_weak_func (char *msg)
{
printf("[%s:%s], Reached weak, with msg: %s\n", __FILE__, __FUNCTION__, msg);
}
typedef int (*func_ptr_t) (char *msg);
func_ptr_t foo_func_ptr = foo_weak_func;
void
invoke_foo_func_ptr (char *msg)
{
printf("Inside %s\n", __FUNCTION__);
if (foo_func_ptr) {
(*foo_func_ptr)(msg);
} else {
printf("foo_func_ptr is NULL\n");
}
}
/* app.c */
#include "foo.h"
int
app_init_func (char *msg)
{
printf("Inside %s:%s\n", __FILE__, __FUNCTION__);
invoke_foo_func_ptr(msg);
}
/* main.c */
int main (int argc, char *argv[])
{
void *dl_handle;
char *lib_name;
app_init_func_t app_init_func;
if (!(argc > 1)) {
printf("Library is not supplied, loading libapp.so\n");
lib_name = strdup("libapp.so");
} else {
lib_name = strdup(argv[2]);
}
printf("Loading library: %s\n", lib_name);
dl_handle = dlopen(lib_name, RTLD_LAZY);
if (!dl_handle) {
printf("Failed to dlopen on %s, error: %s\n", lib_name, dlerror());
exit(1);
}
app_init_func = dlsym(dl_handle, "app_init_func");
if (app_init_func) {
(*app_init_func)("Called via dlsym");
} else {
printf("dlsym did not file app_init_func");
}
return (0);
}
答案 0 :(得分:2)
我的期望是invokes_foo_func_ptr调用强符号,但它总是转到弱符号。
您的期望不正确,一切都按设计运作。
链接单个ELF
二进制文件时,弱符号会丢失为强符号。如果您要将普通(强)函数foo
和弱foo
链接到libfoo.so
,那么强定义就会胜出。
如果您有多个 ELF
图片,其中一些图片内容为foo
,另一些图片内容较弱foo
,首先 { {1}}图片定义ELF
(无论是弱者还是强者)获胜。一旦找到第一个为foo
提供定义的图像,加载程序就不会在其搜索范围内查找任何其他ELF
图像。
不要让我解释特定执行顺序的原因
这是一个令人讨厌的事情。
我猜测你的理由是什么,以及解决方案,但你必须先提供理由。