Sistemul Linux Dlopen în C

Sistemul Linux Dlopen In C



Funcția de bibliotecă dlopen() este o funcție foarte utilă în limbajul C. Funcția încarcă biblioteca în memorie după deschiderea uneia noi. În general, îl folosim pentru a încărca simbolurile bibliotecii care sunt necunoscute la momentul compilării. Dlopen() este o funcție care este folosită în programele noastre. Biblioteca DL implementează dlopen(), definit în Dlfcn.h. Pentru funcția dlopen sunt necesari doi parametri: numele fișierului bibliotecă și steag. Numele fișierului este o bibliotecă dinamică și definește dacă dependențele bibliotecii sunt sau nu calculate imediat. dlopen() returnează un „mâner” care ar trebui privit ca o valoare opac și alte operațiuni de bibliotecă DL îl folosesc. Dacă încercarea de încărcare nu reușește, dlopen() returnează NULL. Dar dlopen() returnează același handle de fișier dacă încarcă aceeași bibliotecă de multe ori.

În timp ce utilizează funcția dlopen, compilatorul nu examinează eventualele erori, deoarece nu cunoaște tipurile și prototipurile pe care le folosim. Implementarea funcției dlopen pentru încărcarea standard nu pare să fie promovată de aceasta, cu excepția câtorva situații minore. Apropo, este o abordare de îmbunătățire a introspecției. Când modulul partajat este utilizat în prezent de un alt program, optimizarea aspectului memoriei nu este interesată în mod deosebit de încărcarea condiționată. Amprenta de memorie nu crește atunci când este încărcată o bibliotecă utilizată anterior. Evitarea monitorizării compilatorului este periculoasă și face o bună scriere a erorilor. În plus, ne lipsește posibila optimizare a compilatorului.

Exemplul 1:

Acum, luați în considerare următorul exemplu pentru a vedea funcționalitatea funcției dlopen în limbajul C. În primul pas, încărcăm câteva biblioteci standard C. Aici, încărcăm noua bibliotecă „dlfcn.h” care este folosită pentru a defini macrocomenzile în timp ce construim argumentul mod dlopen.







Apoi, introducem o altă bibliotecă în programul nostru „gnu/lib-name.h”. Fișierele bibliotecii partajate incluse cu GNU libc sunt găsite de programele utilizatorului conform macrocomenzilor pe care le definește. Biblioteca GNU C oferă bibliotecile fundamentale pentru sistemele de operare GNU și GNU/Linux, precum și o gamă largă de alte sisteme bazate pe Linux. După aceea, avem implementarea metodei principale. În interiorul acestuia, declarăm obiectul pointer „mâner” cu cuvântul cheie void. Declaram o functie pointer sine care are tipul de date double. Există o altă declarație a obiectului pointer „eroare” pentru tratarea erorilor.



După aceea, invocăm funcția dlopen în interiorul obiectului „mâner”. Waterpen-ul are două argumente: LIBM_SO și „RTLD_LAZY”. Aici, „LIBM_SO” este numele fișierului bibliotecă care oferă funcții matematice precum funcțiile trigonometrice. Această bibliotecă partajată este necesară deoarece folosim funcția sine. „RTLD_LAZY” este un alt argument care apelează funcția dlopen. Când se face referire la un anumit simbol pentru prima dată, relocările trebuie efectuate la un moment determinat de implementare.



Deoarece un proces poate să nu facă referire la fiecare simbol dintr-un fișier obiect executabil, specificarea RTLD LAZY ar trebui să îmbunătățească performanța implementărilor care permit legarea dinamică a simbolurilor. În continuare, avem o condiție if-else pentru gestionarea erorilor atunci când obiectul handle nu reușește să efectueze funcția dlopen. Apelăm dlerror pentru a șterge eroarea.





Funcția dlerror() furnizează un șir terminat în nul care poate fi citit de om și specifică raportarea erorii recente cauzate de un apel către unul dintre apelurile API dlopen de la ultimul apel dlerror. Apoi, aruncăm funcția astfel: „(*void**)(&sine)= dlsym(handle, sin)”. Deoarece acest lucru este ciudat, castingul respectă ISO C care evită avertismentele de la compilator. Folosim funcția dlsym care obține calea unui simbol care este specificat în interiorul unui modul de legătură dinamică care este accesibil printr-o funcție dlopen().

De asemenea, efectuăm operația if-else din nou pentru eroarea standard care este generată atunci când dlerror() nu este NULL. Apoi, avem o instrucțiune printf în care specificăm valoarea sinusului care trebuie calculată. În ultimul pas, închidem acel obiect partajat invocând dlclose pentru handle-ul returnat de dlopen().



#include
#include
#include
#include

int
principal ( int argc , char ** argv )
{
gol * mâner ;
dubla ( * a lor ) ( dubla ) ;
char * eroare ;

mâner = dlopen ( LIBM_SO , RTLD_LAZY ) ;
dacă ( ! mâner ) {
fprintf ( stderr , „%s \n ' , eroare ( ) ) ;
Ieșire ( EXIT_FAILURE ) ;
}
eroare ( ) ;

* ( gol ** ) ( & a lor ) = dlsym ( mâner , 'fără' ) ;

dacă ( ( eroare = eroare ( ) ) != NUL ) {
fprintf ( stderr , „%s \n ' , eroare ) ;
Ieșire ( EXIT_FAILURE ) ;
}

printf ( „%f \n ' , ( * a lor ) ( 4.0 ) ) ;
dlclose ( mâner ) ;
Ieșire ( EXIT_SUCCESS ) ;
}

Folosim opțiunea -ldl cu comanda de compilare C, deoarece aceasta este biblioteca pentru interfața conectată dlopen și este necesară. Când se face execuția fișierului dlopen, acesta afișează valoarea sinus a valorii date anterior.

Exemplul 2:

Acum, luăm un alt exemplu de utilizare a funcției dlopen. Încărcăm programul nostru cu toate bibliotecile C necesare pentru implementarea codului dlopen. Apoi, începem programul în cadrul metodei principale. Aici, definim șirul cu declarația variabilei „src”. Apoi declarăm variabilele pointer „strlen”, „handle” și „error”.

Apoi, numim variabila handle și implementăm funcția dlopen. Funcția dlopen introduce biblioteca partajată „libstr.so” pentru funcțiile de gestionare a șirurilor și marcajul „RTLD_LAZY”, care este deja demonstrat în exemplul anterior. Invocăm funcția dlerror din variabila „eroare” pentru a șterge eroarea generată de funcția dlopen. If-else este utilizat pentru a examina erorile.

Apoi, obținem adresa funcției strlen folosind funcția dlsym și verificăm erorile în timp ce facem acest lucru. După aceasta, folosim funcția printf pentru a apela funcția strnlen pentru a returna lungimea șirului dat. În final, închidem biblioteca partajată cu funcția dlclose.

#include
#include
#include
#include
int principal ( gol )
{
char * src = „Bună Linux” ;
int ( * strlen ) ( const char * ) ;
gol * mâner ;
char * eroare ;


mâner = dlopen ( „./libstr.so” , RTLD_LAZY ) ;
eroare = eroare ( ) ;
dacă ( ! mâner || eroare != NUL ) { printf ( „Încercarea bibliotecii a eșuat! \n %s \n ' , eroare ) ;
întoarcere - 1 ; }

strlen = dlsym ( mâner , 'strlen' ) ;
eroare = eroare ( ) ;
dacă ( ! strlen || eroare == NUL ) { printf ( „%s \n ' , eroare ) ; întoarcere - 1 ; }

printf ( „Lungimea șirului este:%d \n ' , strlen ( src ) ) ;
dlclose ( mâner ) ;
întoarcere 0 ;
}

Folosim următoarea comandă pentru execuția programului dat. Aici, indicatorul -lstr este folosit pentru funcția de lungime a șirului și ldl este folosit pentru fișierul de bibliotecă dlopen. Programul compilat oferă lungimea șirului așa cum se arată în shell:

Concluzie

Informațiile sunt furnizate cu privire la funcția dlopen a limbajului C în acest articol. Avem o scurtă introducere a funcției dlopen. Apoi, am implementat două exemple. Funcția returnează un identificator care definește biblioteca deschisă. Adresele funcțiilor din interiorul bibliotecii deschise sunt apoi determinate folosind acest identificator și funcția dlsym. Adresa unei funcții dintr-o bibliotecă care a fost deja deschisă folosind dlopen poate fi găsită folosind funcția dlsym.