2013-02-19 11 views
7

Mi piacerebbe scrivere un codice C (ok se funziona solo su Linux) per caricare dinamicamente una nuova libreria condivisa e quindi richiamare un metodo da esso (da determinare in fase di runtime). Sembra che questo sia già possibile perché java può caricare le librerie native in modo dinamico e quindi richiamare i metodi da esse.Come caricare dinamicamente la mia libreria e invocare un metodo al suo interno?

Per esempio, mi piacerebbe fare qualcosa di simile:

int main() { 
    libinfo_t * lib_details = load_shared_library("libfoo.so"); 
    run_method(lib_details, "bar", 7); 
} 

questo sarebbe invocare il 'bar' metodo con argomento 7 (bar è un metodo compilato nel libfoo.so).

Usa carcasse:

mi piacerebbe compilare un binario che carica tutte le librerie condivise in una directory, e corre qualche metodo da ciascuno, nel contesto di memoria del programma originale. Mi piacerebbe essere in grado di abilitare o disabilitare rapidamente una libreria condivisa aggiungendola/rimuovendola da una directory.

Proof of concept:

Sembra che questo dovrebbe essere possibile, in base al modo di Java riesce a collegarsi con il codice JNI in modo dinamico. È possibile utilizzare System.load() e caricare la libreria desiderata. Accoppiato con la compilazione dalla memoria, sembra che ti consentirebbe di eseguire una funzione arbitraria da una libreria arbitraria. http://www.java2s.com/Code/Java/JDK-6/CompilingfromMemory.htm

Le cose che ho provato:

  1. Ho guardato la pagina di manuale per 'USELIB', che sembra utile, ma non sono sicuro di cosa fare con la libreria una volta che ho caricato.

  2. Un po 'di googling restituito http://dyncall.org/, ma questo non è esattamente quello che mi serve - questo progetto richiede ancora un puntatore a funzione per effettuare la chiamata di funzione.

Sarei grato per qualsiasi puntatore su dove guardare dopo, anche senza una risposta concreta. Grazie!

+0

C non hanno metodi ma funzioni. –

risposta

9

Linux ha un'API molto completa per questo. È l'API dlopen(3).

In primo luogo, si chiama dlopen con un nome di file per ottenere un handle libreria condivisa:

void* lib = dlopen("./lib.so"); 

Than, per ottenere un puntatore a funzione per una funzione in questa biblioteca:

int (*func)() = dlsym(lib, "thing"); 

Utilizzare questo puntatore come preferisce.

Infine, quando hai finito:

dlclose(lib) 

Nota: Ricordatevi di fare il controllo degli errori!

+1

Wow, grazie per la rapida risposta! Sembra esattamente quello che stavo cercando. – jstrom

+1

@jstrom: Sicuro! Felice di aiutare. A proposito, benvenuto in SO! Buona prima domanda Spero torni! Sembra anche che tu abbia letto le FAQ - yay! :). – Linuxios

+2

Si potrebbe voler mettere un '/' nel percorso, ad esempio 'dlopen (" ./ lib.così ");' altrimenti 'LD_LIBRARY_PATH' o viene utilizzato l'equivalente integrato –

Problemi correlati