我们有一个程序链接在许多静态库中,这些静态库可能会也可能不会根据编译选项定义多个符号。在OS X上,我们使用带有NULL句柄的dlsym(3)
来获取符号地址。但是,在Linux上,dlsym(3)
始终返回NULL。
考虑一个简单的程序(下面的源代码),它链接在包含函数和变量的静态库中,并尝试打印它们的地址。我们可以检查程序是否包含符号:
$ nm -C test | grep "test\(func\|var\)"
0000000000400715 T testFunc
0000000000601050 B testVar
但是,当程序运行时,无法找到它们:
$ ./test
testVar: (nil)
testFunc: (nil)
我们正在尝试使用glibc的dlsym(3)
实现在Linux上做什么?
(对不起空格)
LDFLAGS=-L.
LDLIBS=-Wl,--whole-archive -ltest -Wl,--no-whole-archive -ldl
libtest.o: libtest.c libtest.h
libtest.a: libtest.o
test: test.o libtest.a
clean:
-rm -f test test.o libtest.o libtest.a
#pragma once
extern void *testVar;
extern int testFunc(int);
#include "libtest.h"
void *testVar;
int testFunc(int x) { return x + 42; }
#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>
int main(int argc, char *argv[]) {
void *handle = dlopen(NULL, 0);
void *symbol = dlsym(handle, "testVar");
printf("testVar: %p\n", symbol);
symbol = dlsym(handle, "testFunc");
printf("testFunc: %p\n", symbol);
return 0;
}
答案 0 :(得分:4)
您应该将您的计划与-rdynamic
(或ld(1) --export-dynamic
)相关联,以便
LDFLAGS += -rdynamic -L.
然后所有符号都在动态符号表中,dlsym
visibility
attribute可能很有意思。