2013-01-12 16 views
5

dlopen(NULL, ...)'u çalıştırma ve statik olarak derlenmiş bir ikili için semboller alma umudu var mı?Statik bir ikilide dlsym kullanın

Örneğin, aşağıdaki kodla, program dinamik olarak derlenmişse semboller alabilirim ve -rdynamic kullanıyorum. foo.c için

$ 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 

kaynak şöyle:

#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; 
} 

cevap

4

Dlopen (BOŞ çalışan bir umut var mı

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

Ama -static ile ben Şifreli bir hata iletisi alıyorum. ..) ve statik olarak derlenmiş bir ikili için semboller mi alıyorsunuz? En Unix'te

sayılı

hatta aynı anda -static ve -ldl ile bağlayamazsınız. Glibc kullanarak yapabilirsiniz, ancak bunu yapmanın yararı çok sınırlı sınırlı. Temel olarak, bu yetenek sadece /etc/nsswitch.conf dosyasını destekler ve başka bir şey değildir.

Yaptığınız dinamik aramada no noktasında da var.

sadece, örneğin bir tablo koymak, komut satırı argümanları bağlı çağrılacak foo, bar veya baz birine izin çalışıyorsanız

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

if (&foo != 0) { 
    // foo was linked in, call it 
    foo(); 
} 
: Eğer içinde bağlıysa "belki" foo arama ve aksi bir şey yapmak çalışıyorsanız

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)(); 

ardından zayıf başvuruları kullanmak

İlgili konular