Sistema Linux Dlopen in C

Sistema Linux Dlopen In C



La funzione di libreria dlopen() è una funzione molto utile nel linguaggio C. La funzione carica la libreria in memoria dopo averne aperta una nuova. Generalmente lo usiamo per caricare i simboli della libreria che sono sconosciuti al momento della compilazione. Dlopen() è una funzione utilizzata nei nostri programmi. La libreria DL implementa dlopen(), definita in Dlfcn.h. Per la funzione dlopen sono richiesti due parametri: il nome del file di libreria e il flag. Il nome del file è una libreria dinamica e definisce se le dipendenze della libreria vengono calcolate immediatamente o meno. Il dlopen() restituisce un 'handle' che dovrebbe essere considerato un valore opaco e altre operazioni della libreria DL lo usano. Se il tentativo di caricamento non riesce, dlopen() restituisce NULL. Ma dlopen() restituisce lo stesso handle di file se carica la stessa libreria molte volte.

Durante l'utilizzo della funzione dlopen, il compilatore non esamina potenziali errori poiché non è a conoscenza dei tipi e dei prototipi che stiamo utilizzando. L'implementazione della funzione dlopen per il caricamento standard non sembra essere promossa da essa, ad eccezione di alcune situazioni minori. A proposito, è un approccio per migliorare l'introspezione. Quando il modulo condiviso è attualmente utilizzato da un altro programma, l'ottimizzazione del layout della memoria non è particolarmente interessata al caricamento condizionato. Il footprint di memoria non aumenta quando viene caricata una libreria utilizzata in precedenza. Evitare il monitoraggio del compilatore è pericoloso e crea una buona scrittura di bug. Inoltre, ci manca la possibile ottimizzazione del compilatore.

Esempio 1:

Consideriamo ora il seguente esempio per vedere la funzionalità della funzione dlopen nel linguaggio C. Nel primo passaggio, carichiamo alcune librerie standard C. Qui carichiamo la nuova libreria “dlfcn.h” che viene usata per definire le macro mentre costruiamo l'argomento dlopen mode.







Quindi, introduciamo un'altra libreria all'interno del nostro programma 'gnu/lib-name.h'. I file della libreria condivisa inclusi con GNU libc vengono trovati dai programmi utente in base alle macro che definisce. La libreria GNU C offre le librerie fondamentali per i sistemi operativi GNU e GNU/Linux, nonché un'ampia gamma di altri sistemi basati su Linux. Successivamente, abbiamo l'implementazione del metodo principale. All'interno dichiariamo l'oggetto puntatore 'handle' con la parola chiave void. Dichiariamo una funzione puntatore seno che ha il tipo di dati double. Esiste un'altra dichiarazione dell'oggetto puntatore 'errore' per la gestione degli errori.



Successivamente, invochiamo la funzione dlopen all'interno dell'oggetto 'handle'. Il dlopen accetta due argomenti: LIBM_SO e “RTLD_LAZY”. Qui, 'LIBM_SO' è il nome del file di libreria che fornisce funzioni matematiche come le funzioni trigonometriche. Questa libreria condivisa è necessaria poiché utilizziamo la funzione seno. Il 'RTLD_LAZY' è un altro argomento che chiama la funzione dlopen. Quando si fa riferimento a un determinato simbolo per la prima volta, i trasferimenti devono essere effettuati in un momento determinato dall'implementazione.



Poiché un processo potrebbe non fare riferimento a tutti i simboli in un file oggetto eseguibile, la specifica di RTLD LAZY dovrebbe migliorare le prestazioni sulle implementazioni che abilitano l'associazione dinamica dei simboli. Successivamente, abbiamo una condizione if-else per la gestione degli errori quando l'oggetto handle non riesce a eseguire la funzione dlopen. Chiamiamo il dlerror per cancellare l'errore.





La funzione dlerror() fornisce una stringa con terminazione null leggibile e specifica la segnalazione dell'errore recente causato da una chiamata a una delle chiamate API dlopen dall'ultima chiamata dlerror. Quindi, lanciamo la funzione in questo modo: “(*void**)(&sine)= dlsym(handle, sin)”. Poiché questo è strano, il casting è conforme a ISO C che evita gli avvisi del compilatore. Utilizziamo la funzione dlsym che ottiene il percorso di un simbolo specificato all'interno di un modulo di collegamento dinamico accessibile tramite una funzione dlopen().

Inoltre, eseguiamo nuovamente l'operazione if-else per l'errore standard che viene generato quando dlerror() non è NULL. Quindi, abbiamo un'istruzione printf in cui specifichiamo il valore del seno da calcolare. Nell'ultimo passaggio, chiudiamo quell'oggetto condiviso invocando dlclose per l'handle restituito da dlopen().



#include
#include
#include
#include

int
principale ( int arg , car ** argv )
{
vuoto * maneggiare ;
Doppio ( * il loro ) ( Doppio ) ;
car * errore ;

maneggiare = dlopen ( LIBM_SO , RTLD_LAZY ) ;
Se ( ! maneggiare ) {
fprintf ( stderr , '%S \n ' , dlerror ( ) ) ;
Uscita ( EXIT_FAILURE ) ;
}
dlerror ( ) ;

* ( vuoto ** ) ( & il loro ) = dissim ( maneggiare , 'senza' ) ;

Se ( ( errore = dlerror ( ) ) != NULLO ) {
fprintf ( stderr , '%S \n ' , errore ) ;
Uscita ( EXIT_FAILURE ) ;
}

stampa f ( '%f \n ' , ( * il loro ) ( 4.0 ) ) ;
dlchiudi ( maneggiare ) ;
Uscita ( EXIT_SUCCESS ) ;
}

Usiamo l'opzione -ldl con il comando di compilazione C poiché questa è la libreria per l'interfaccia collegata dlopen ed è richiesta. Quando viene eseguita l'esecuzione del file dlopen, viene visualizzato il valore seno del valore precedentemente dato.

Esempio 2:

Ora prendiamo un altro esempio di utilizzo della funzione dlopen. Carichiamo il nostro programma con tutte le librerie C richieste per l'implementazione del codice dlopen. Quindi, avviamo il nostro programma all'interno del metodo principale. Definiamo qui la stringa con la dichiarazione della variabile “src”. Dichiariamo quindi le variabili del puntatore “strlen”, “handle” ed “error”.

Successivamente, chiamiamo la variabile handle e distribuiamo la funzione dlopen. La funzione dlopen inserisce la libreria condivisa “libstr.so” per le funzioni di gestione delle stringhe e il flag “RTLD_LAZY” già mostrato nell'esempio precedente. Invochiamo la funzione dlerror all'interno della variabile 'error' per cancellare l'errore generato dalla funzione dlopen. L'if-else viene utilizzato per esaminare gli errori.

Quindi, otteniamo l'indirizzo della funzione strlen usando la funzione dlsym e verifichiamo gli errori mentre lo facciamo. Successivamente, utilizziamo la funzione printf per chiamare la funzione strnlen per restituire la lunghezza della stringa data. Alla fine, chiudiamo la libreria condivisa con la funzione dlclose.

#include
#include
#include
#include
int principale ( vuoto )
{
car * src = 'Ciao Linux' ;
int ( * strlen ) ( cost car * ) ;
vuoto * maneggiare ;
car * errore ;


maneggiare = dlopen ( './libstr.so' , RTLD_LAZY ) ;
errore = dlerror ( ) ;
Se ( ! maneggiare || errore != NULLO ) { stampa f ( 'Tentativo di caricamento della libreria fallito! \n %S \n ' , errore ) ;
Restituzione - 1 ; }

strlen = dissim ( maneggiare , 'strlen' ) ;
errore = dlerror ( ) ;
Se ( ! strlen || errore == NULLO ) { stampa f ( '%S \n ' , errore ) ; Restituzione - 1 ; }

stampa f ( 'La lunghezza della stringa è:%d \n ' , strlen ( src ) ) ;
dlchiudi ( maneggiare ) ;
Restituzione 0 ;
}

Usiamo il seguente comando per l'esecuzione del programma dato. Qui, il flag -lstr viene utilizzato per la funzione di lunghezza della stringa e ldl viene utilizzato per il file di libreria dlopen. Il programma compilato fornisce la lunghezza della stringa come mostrato nella shell:

Conclusione

Le informazioni sono fornite in merito alla funzione dlopen del linguaggio C in questo articolo. Abbiamo una breve introduzione della funzione dlopen. Quindi, abbiamo implementato due esempi. La funzione restituisce un identificatore che definisce la libreria aperta. Gli indirizzi delle funzioni all'interno della libreria aperta vengono quindi determinati utilizzando questo identificatore e la funzione dlsym. L'indirizzo di una funzione all'interno di una libreria che è già stata aperta usando dlopen può essere trovato usando la funzione dlsym.