2013-01-12 26 views
5

是否有任何希望運行dlopen(NULL, ...)並獲取靜態編譯二進制文件的符號?在靜態二進制文件上使用dlsym

例如,如果程序是動態編譯的,並且使用-rdynamic,則使用以下代碼可以獲得符號。

$ gcc -o foo foo.c -ldl -rdynamic 
$ ./foo bar 
In bar! 

但隨着-static我得到一個神祕的錯誤消息:

$ gcc -static -o foo foo.c -ldl -rdynamic 
/tmp/cc5LSrI5.o: In function `main': 
foo.c:(.text+0x3a): warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking 
$ ./foo bar 
/lib/x86_64-linux-gnu/: cannot read file data: Is a directory 

的源foo.c如下:

#include <dlfcn.h> 
#include <stdio.h> 

int foo() { printf("In foo!\n"); } 
int bar() { printf("In bar!\n"); } 

int main(int argc, char**argv) 
{ 
    void *handle; 
    handle = dlopen(NULL, RTLD_NOW|RTLD_GLOBAL); 
    if (handle == NULL) { 
    fprintf(stderr, "%s\n", dlerror()); 
    return 1; 
    } 

    typedef void (*function)(); 
    function f = (function) dlsym(handle, argv[1]); 
    if (f == NULL) { 
    fprintf(stderr, "%s\n", dlerror()); 
    return 2; 
    } 
    f(); 

    return 0; 
} 

回答

4

是否有正在運行的dlopen(NULL的希望。 ..)並獲得一個靜態編譯的二進制符號?

在大多數UNIX系統,你甚至不能-static-ldl同時鏈接。你可以使用glibc,但是這樣做的效用是非常有限的。基本上,這個能力只是用來支持/etc/nsswitch.conf,而不是其他的。

還有沒有點在做你做的動態查找。

如果你想允許的foobarbaz一個根據命令行參數來調用,只是把一個表,例如

struct { const char *fname, void (*fn)(void) } table[] = 
    { {"foo", &foo}, {"bar", &bar}, ...}; 

for (int i = 0; i < ...; ++i) 
    if (strcmp(argv[1], table[i].fname) == 0) 
    // found the entry, call it 
    (*table[i].fn)(); 

如果你想「也許」叫foo如果是掛在,什麼事都不做,否則,則使用弱引用:

extern void foo(void) __attribute((weak)); 

if (&foo != 0) { 
    // foo was linked in, call it 
    foo(); 
} 
相關問題