Domanda

Sto scrivendo un codice che utilizza librerie condivise dinamiche come plugin.

La mia riga di comando per la costruzione delle biblioteche condivise sembra:

cc -shared -fPIC -o module.so -g -Wall module.c

All'interno del modulo, posso chiamare funzioni che si trovano in qualsiasi altra libreria condivisa che è stata caricata all'interno dell'eseguibile principale.

Tuttavia non posso accedere alle funzioni (esportate) che si trovano nell'eseguibile stesso (ottengo undefined symbol errori).

La mia chiamata a dlopen Somiglia a questo:

void *handle = dlopen(plugin, RTLD_NOW);

Qualcuno può consigliare come il mio modulo può richiamare al mio eseguibile, senza dover inserire tutte le funzioni di utilità dell'eseguibile in un'altra libreria condivisa?

È stato utile?

Soluzione 2

Ho trovato la risposta da solo.

Ho dovuto aggiungere il --export-dynamic Flag alle opzioni di collegamento per l'eseguibile principale.

Quando si crea un eseguibile dinamicamente collegato, aggiungere tutti i simboli alla tabella dei simboli dinamici. La tabella dei simboli dinamici è l'insieme di simboli visibili da oggetti dinamici in fase di esecuzione.

Se non si utilizza questa opzione, la tabella dei simboli dinamici conterrà normalmente solo quei simboli a cui si fa riferimento da alcuni oggetti dinamici menzionati nel collegamento.

Se si utilizza "dlopen" per caricare un oggetto dinamico che deve fare riferimento ai simboli definiti dal programma, piuttosto che da qualche altro oggetto dinamico, probabilmente dovrai utilizzare questa opzione quando si collega il programma stesso.

Altri suggerimenti

La soluzione corretta è aggiungere -rdynamic al comando collegamento dell'eseguibile principale. Ciò aggiungerà l'opzione appropriata a ld (che, quando si usa GNU ld, capita di esserlo --export-dynamic).

Aggiunta --export-dynamic direttamente è tecnicamente errato: è un'opzione di linker, e quindi dovrebbe essere aggiunta come -Wl,--export-dynamic, o -Wl,-E. Questo è anche meno portatile di -rdynamic (Altri linker hanno un equivalente, ma l'opzione stessa è diversa).

Quando ho riscontrato lo stesso problema, ho appena usato la seguente soluzione. Prima di caricare qualsiasi plug -in, basta caricare il programma stesso, portando i suoi simboli su tabelle dinamiche:

dlopen(NULL,RTLD_NOW|RTLD_GLOBAL);

Penso che la soluzione sia migliore. Il motivo è che risolve anche lo stesso problema se tu

a) Il tuo programma (o un modulo di triver party) è collegato (non in runtime) contro la libreria condivisa, che i simboli devono essere in tabella dinamica;

b) non può ricompilare quel modulo con bandiera -rsnamica.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top