2016-04-18 18 views
14

-rdynamic (veya bağlantı düzeyinde --export-dynamic) tam olarak ne yapar ve -fvisibility* bayrakları veya görünürlüğü pragma s ve __attribute__ s tarafından tanımlanan sembol görünürlüğü ile nasıl ilişkilidir?Tam olarak ne gerekli ve ne zaman gerekli?

--export-dynamic için ld(1) bahseder:

... Bunun yerine bazı diğer dinamik daha "Dlopen" kullanmak program tarafından belirlenen semboller geri başvurmak gerekir dinamik bir nesneyi yüklemek için ise nesnesi, daha sonra programın kendisini bağlarken bu seçeneği kullanmak için muhtemelen gerekir. ...

Bunu tamamen anladığımdan emin değilim. -rdynamic olmadan çalışmayan ancak bununla birlikte çalışan bir örnek verebilir misiniz?

Düzenleme: Aslında bir kukla kütüphanelerin çift derleme çalıştı (tek dosya, çok dosya, çeşitli -O seviyeleri, bazı arası işlev çağrıları, bazı gizli semboller, bazı görünür) ile ve -rdynamic olmadan ve şu ana kadar byte-özdeş çıkışları elde ettim (diğer tüm bayrakları sabit tutarken), ki bu oldukça şaşırtıcıdır.

cevap

16

İşte, -rdynamic kullanımını göstermek için basit bir örnek proje.

bar.c

extern void foo(void); 

void bar(void) 
{ 
    foo(); 
} 

main.c İşte

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

void foo(void) 
{ 
    puts("Hello world"); 
} 

int main(void) 
{ 
    void * dlh = dlopen("./libbar.so", RTLD_NOW); 
    if (!dlh) { 
     fprintf(stderr, "%s\n", dlerror()); 
     exit(EXIT_FAILURE); 
    } 
    void (*bar)(void) = dlsym(dlh,"bar"); 
    if (!bar) { 
     fprintf(stderr, "%s\n", dlerror()); 
     exit(EXIT_FAILURE); 
    } 
    bar(); 
    return 0; 
} 

Makefile

.PHONY: all clean test 

LDEXTRAFLAGS ?= 

all: prog 

bar.o: bar.c 
    gcc -c -Wall -fpic -o [email protected] $< 

libbar.so: bar.o 
    gcc -shared -o [email protected] $< 

main.o: main.c 
    gcc -c -Wall -o [email protected] $< 

prog: main.o | libbar.so 
    gcc $(LDEXTRAFLAGS) -o [email protected] $< -L. -lbar -ldl 

clean: 
    rm -f *.o *.so prog 

test: prog 
    ./$< 

, bar.c olmak Paylaşılan kitaplık libbar.so gelir ve main.cdlopen s libbar bir program olur ve bu kitaplıktan bar() çağrıları. bar.c numaralı bar() numaralı foo() numaralı telefon numaraları, main.c numaralı telefon numarasından tanımlanmıştır. -rdynamic olmadan Yani

:

$ make test 
gcc -c -Wall -o main.o main.c 
gcc -c -Wall -fpic -o bar.o bar.c 
gcc -shared -o libbar.so bar.o 
gcc -o prog main.o -L. -lbar -ldl 
./prog 
./libbar.so: undefined symbol: foo 
Makefile:23: recipe for target 'test' failed 

Ve -rdynamic ile

:

$ make clean 
rm -f *.o *.so prog 
$ make test LDEXTRAFLAGS=-rdynamic 
gcc -c -Wall -o main.o main.c 
gcc -c -Wall -fpic -o bar.o bar.c 
gcc -shared -o libbar.so bar.o 
gcc -rdynamic -o prog main.o -L. -lbar -ldl 
./prog 
Hello world 
+0

Örneğin, man sayfasının ne anlama geldiğini mükemmel bir şekilde açıklar. Çok teşekkürler! – PSkocik

İlgili konular