Linux Dlopen System i C

Linux Dlopen System I C



Bibliotekfunksjonen dlopen() er en veldig nyttig funksjon i C-språket. Funksjonen laster biblioteket inn i minnet etter å ha åpnet et nytt. Vi bruker det vanligvis til å laste inn biblioteksymbolene som er ukjente på kompileringstidspunktet. Dlopen() er en funksjon som brukes i våre programmer. DL-biblioteket implementerer dlopen(), definert i Dlfcn.h. To parametere kreves for dlopen-funksjonen: navnet på bibliotekfilen og flagget. Filens navn er et dynamisk bibliotek, og det definerer hvorvidt bibliotekets avhengigheter beregnes med en gang. Dlopen() returnerer et 'håndtak' som bør betraktes som en ugjennomsiktig verdi, og andre DL-biblioteksoperasjoner bruker dette. Hvis forsøket på å laste er mislykket, returnerer dlopen() NULL. Men dlopen() returnerer det samme filhåndtaket hvis det laster det samme biblioteket mange ganger.

Mens han bruker dlopen-funksjonen, undersøker ikke kompilatoren for potensielle feil siden den ikke er klar over typene og prototypene vi bruker. Utplasseringen av dlopen-funksjonen for standard lasting ser ikke ut til å være fremmet av den, bortsett fra noen få mindre situasjoner. Forresten, det er en tilnærming for å forbedre introspeksjon. Når den delte modulen for øyeblikket brukes av et annet program, er ikke minnelayoutoptimaliseringen spesielt interessert i betinget lasting. Minnefotavtrykket øker ikke når et tidligere brukt bibliotek lastes inn. Å unngå kompilatorovervåking er farlig og gir god feilskriving. I tillegg mangler vi mulig kompilatoroptimalisering.

Eksempel 1:

Tenk nå på følgende eksempel for å se funksjonaliteten til dlopen-funksjonen i C-språket. I det første trinnet laster vi inn noen C-standardbiblioteker. Her laster vi det nye biblioteket 'dlfcn.h' som brukes til å definere makroene mens vi konstruerer dlopen-modusargumentet.







Deretter introduserer vi et annet bibliotek i programmet vårt 'gnu/lib-name.h'. De delte bibliotekfilene som følger med GNU libc, blir funnet av brukerprogrammene i henhold til makroene den definerer. GNU C-biblioteket tilbyr de grunnleggende bibliotekene for GNU- og GNU/Linux-operativsystemene samt et bredt spekter av andre Linux-baserte systemer. Etter det har vi hovedmetodeimplementeringen. Inne i det erklærer vi pekerobjektet 'håndtak' med nøkkelordet void. Vi erklærer en pekersinusfunksjon som har datatypen dobbel. Det er en annen erklæring om pekerobjektet 'feil' for feilhåndtering.



Etter det påkaller vi dlopen-funksjonen inne i 'håndtak'-objektet. Dlopen tar to argumenter: LIBM_SO og 'RTLD_LAZY'. Her er 'LIBM_SO' navnet på bibliotekfilen som gir matematiske funksjoner som trigonometriske funksjoner. Dette delte biblioteket er nødvendig da vi bruker sinusfunksjonen. 'RTLD_LAZY' er et annet argument som kaller dlopen-funksjonen. Når et gitt symbol refereres første gang, må flytting utføres på et tidspunkt bestemt av implementeringen.



Siden en prosess kanskje ikke refererer til hvert symbol i en kjørbar objektfil, bør spesifisering av RTLD LAZY forbedre ytelsen på implementeringer som aktiverer dynamisk symbolbinding. Deretter har vi en if-else-betingelse for feilhåndtering når handle-objektet ikke klarer å utføre dlopen-funksjonen. Vi ringer dlerror for å fjerne feilen.





Funksjonen dlerror() gir en null-terminert streng som er lesbar for mennesker og spesifiserer rapporteringen av den nylige feilen som er forårsaket av et kall til et av dlopen API-kallene siden siste dlerror-kall. Deretter kaster vi funksjonen slik: '(*void**)(&sine)= dlsym(handle, sin)'. Siden dette er merkelig, samsvarer casting med ISO C som unngår advarsler fra kompilatoren. Vi bruker dlsym-funksjonen som får banen til et symbol som er spesifisert i en dynamisk lenkemodul som er tilgjengelig via en dlopen()-funksjon.

Dessuten utfører vi if-else-operasjonen på nytt for standardfeilen som genereres når dlerror() ikke er NULL. Deretter har vi en printf-setning der vi spesifiserer sinusverdien som skal beregnes. I det siste trinnet lukker vi det delte objektet ved å påkalle dlclose for håndtaket som returneres av dlopen().



#include
#include
#include
#include

int
hoved- ( int argc , røye ** argv )
{
tomrom * håndtak ;
dobbelt ( * sine ) ( dobbelt ) ;
røye * feil ;

håndtak = dlopen ( LIBM_SO , RTLD_LAZY ) ;
hvis ( ! håndtak ) {
fprintf ( stderr , '%s \n ' , dlerror ( ) ) ;
exit ( EXIT_FAILURE ) ;
}
dlerror ( ) ;

* ( tomrom ** ) ( & sine ) = dlsym ( håndtak , 'uten' ) ;

hvis ( ( feil = dlerror ( ) ) != NULL ) {
fprintf ( stderr , '%s \n ' , feil ) ;
exit ( EXIT_FAILURE ) ;
}

printf ( '%f \n ' , ( * sine ) ( 4.0 ) ) ;
lukk ( håndtak ) ;
exit ( EXIT_SUCCESS ) ;
}

Vi bruker -ldl-alternativet med C-kompileringskommandoen siden dette er biblioteket for det dlopen-lenkede grensesnittet og det er nødvendig. Når kjøringen av dlopen-filen er utført, viser den sinusverdien til den tidligere oppgitte verdien.

Eksempel 2:

Nå tar vi et annet eksempel på bruk av dlopen-funksjonen. Vi laster programmet vårt med alle nødvendige C-biblioteker for implementering av dlopen-koden. Deretter starter vi programmet vårt i hovedmetoden. Her definerer vi strengen med deklarasjonen av variabelen 'src'. Vi erklærer deretter pekervariablene 'strlen', 'handle' og 'feil'.

Deretter kaller vi handlevariabelen og distribuerer dlopen-funksjonen. Dlopen-funksjonen legger inn det delte biblioteket 'libstr.so' for strenghåndteringsfunksjoner og flagget 'RTLD_LAZY' som allerede er demonstrert i forrige eksempel. Vi påkaller dlerror-funksjonen inne i 'error'-variabelen for å fjerne feilen generert av dlopen-funksjonen. Hvis-else brukes til å undersøke feilene.

Deretter får vi strlen-funksjonens adresse ved å bruke dlsym-funksjonen og verifiserer feilene mens vi gjør dette. Etter dette bruker vi printf-funksjonen til å kalle strnlen-funksjonen for å returnere lengden på den gitte strengen. Til slutt lukker vi det delte biblioteket med dlclose-funksjonen.

#include
#include
#include
#include
int hoved- ( tomrom )
{
røye * src = 'Hei Linux' ;
int ( * strlen ) ( konst røye * ) ;
tomrom * håndtak ;
røye * feil ;


håndtak = dlopen ( './libstr.so' , RTLD_LAZY ) ;
feil = dlerror ( ) ;
hvis ( ! håndtak || feil != NULL ) { printf ( «Lasting av bibliotekforsøk mislyktes! \n %s \n ' , feil ) ;
komme tilbake - 1 ; }

strlen = dlsym ( håndtak , 'strlen' ) ;
feil = dlerror ( ) ;
hvis ( ! strlen || feil == NULL ) { printf ( '%s \n ' , feil ) ; komme tilbake - 1 ; }

printf ( 'Lengden på strengen er:%d \n ' , strlen ( src ) ) ;
lukk ( håndtak ) ;
komme tilbake 0 ;
}

Vi bruker følgende kommando for å utføre det gitte programmet. Her brukes -lstr-flagget for strenglengde-funksjonen og ldl-en for dlopen-biblioteksfilen. Det kompilerte programmet gir lengden på strengen som vist i skallet:

Konklusjon

Informasjonen er gitt om dlopen-funksjonen til C-språket i denne artikkelen. Vi har en kort introduksjon av dlopen-funksjonen. Deretter implementerte vi to eksempler. Funksjonen returnerer en identifikator som definerer det åpnede biblioteket. Adressene til funksjonene inne i det åpnede biblioteket bestemmes deretter ved hjelp av denne identifikatoren og dlsym-funksjonen. En funksjons adresse i et bibliotek som allerede er åpnet ved hjelp av dlopen kan bli funnet ved å bruke dlsym-funksjonen.