Linux Dlopen System i C

Linux Dlopen System I C



Biblioteksfunktionen dlopen() er en meget nyttig funktion i C-sproget. Funktionen indlæser biblioteket i hukommelsen efter åbning af et nyt. Vi bruger det generelt til at indlæse bibliotekssymboler, der er ukendte på kompileringstidspunktet. Dlopen() er en funktion, der bruges i vores programmer. DL-biblioteket implementerer dlopen(), defineret i Dlfcn.h. To parametre er nødvendige for dlopen-funktionen: navnet på biblioteksfilen og flaget. Filens navn er et dynamisk bibliotek, og det definerer, om bibliotekets afhængigheder beregnes med det samme. Dlopen() returnerer et 'håndtag', som skal betragtes som en uigennemsigtig værdi, og andre DL-biblioteksoperationer bruger dette. Hvis forsøget på at indlæse mislykkes, returnerer dlopen() NULL. Men dlopen() returnerer det samme filhåndtag, hvis det indlæser det samme bibliotek mange gange.

Mens compileren bruger dlopen-funktionen, undersøger den ikke for potentielle fejl, da den ikke er klar over de typer og prototyper, vi bruger. Udrulningen af ​​dlopen-funktionen til standardbelastning ser ikke ud til at være fremmet af den, bortset fra nogle få mindre situationer. Det er i øvrigt en tilgang til at forbedre introspektion. Når det delte modul i øjeblikket bruges af et andet program, er hukommelseslayoutoptimeringen ikke særlig interesseret i betinget indlæsning. Hukommelsesfodaftrykket øges ikke, når et tidligere brugt bibliotek indlæses. At undgå compiler-overvågning er farligt og giver god fejlskrivning. Derudover mangler vi den mulige compiler-optimering.

Eksempel 1:

Overvej nu følgende eksempel for at se funktionaliteten af ​​dlopen-funktionen i C-sproget. I det første trin indlæser vi nogle C-standardbiblioteker. Her indlæser vi det nye bibliotek 'dlfcn.h', som bruges til at definere makroerne, mens vi konstruerer argumentet dlopen mode.







Derefter introducerer vi et andet bibliotek i vores program 'gnu/lib-name.h'. De delte biblioteksfiler, der er inkluderet i GNU libc, findes af brugerprogrammerne i henhold til de makroer, den definerer. GNU C-biblioteket tilbyder de grundlæggende biblioteker til GNU- og GNU/Linux-operativsystemerne samt en lang række andre Linux-baserede systemer. Derefter har vi den vigtigste metodeimplementering. Inde i det erklærer vi pointerobjektet 'håndtag' med nøgleordet void. Vi erklærer en pointersinusfunktion, der har datatypen dobbelt. Der er en anden erklæring af pointerobjektet 'fejl' til fejlhåndtering.



Derefter kalder vi dlopen-funktionen inde i 'håndtag'-objektet. Dlopen tager to argumenter: LIBM_SO og 'RTLD_LAZY'. Her er 'LIBM_SO' navnet på biblioteksfilen, som giver matematiske funktioner som trigonometriske funktioner. Dette delte bibliotek er påkrævet, da vi bruger sinusfunktionen. 'RTLD_LAZY' er et andet argument, der kalder dlopen-funktionen. Når der henvises til et givet symbol første gang, skal flytninger udføres på et tidspunkt, der er bestemt af implementeringen.



Da en proces muligvis ikke refererer til hvert symbol i en eksekverbar objektfil, bør angivelse af RTLD LAZY forbedre ydeevnen på implementeringer, der muliggør den dynamiske symbolbinding. Dernæst har vi en if-else-betingelse for fejlhåndtering, når handleobjektet ikke kan udføre dlopen-funktionen. Vi ringer til dlerror for at fjerne fejlen.





Funktionen dlerror() giver en null-termineret streng, der kan læses af mennesker og specificerer rapporteringen af ​​den seneste fejl, der er forårsaget af et kald til et af dlopen API-kaldene siden det sidste dlerror-kald. Derefter kaster vi funktionen sådan her: '(*void**)(&sine)= dlsym(handle, sin)'. Da dette er mærkeligt, overholder casting ISO C, hvilket undgår advarsler fra compileren. Vi anvender dlsym-funktionen, som får stien til et symbol, der er specificeret inde i et dynamisk link-modul, som er tilgængeligt via en dlopen()-funktion.

Vi udfører også if-else-operationen igen for standardfejlen, som genereres, når dlerror() ikke er NULL. Så har vi en printf-sætning, hvor vi angiver sinusværdien, der skal beregnes. I det sidste trin lukker vi det delte objekt ved at påkalde dlclose for håndtaget returneret af dlopen().



#include
#include
#include
#include

int
vigtigste ( int argc , char ** argv )
{
ugyldig * håndtere ;
dobbelt ( * deres ) ( dobbelt ) ;
char * fejl ;

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

* ( ugyldig ** ) ( & deres ) = dlsym ( håndtere , 'uden' ) ;

hvis ( ( fejl = dlerror ( ) ) != NUL ) {
fprintf ( stderr , '%s \n ' , fejl ) ;
Afslut ( EXIT_FAILURE ) ;
}

printf ( '%f \n ' , ( * deres ) ( 4.0 ) ) ;
luk ( håndtere ) ;
Afslut ( EXIT_SUCCESS ) ;
}

Vi bruger -ldl-indstillingen med C-kompileringskommandoen, da dette er biblioteket for den dlopen-linkede grænseflade, og det er påkrævet. Når udførelsen af ​​dlopen-filen er lavet, viser den sinusværdien for den tidligere givne værdi.

Eksempel 2:

Nu tager vi et andet eksempel på brug af dlopen-funktionen. Vi indlæser vores program med alle de nødvendige C-biblioteker til implementering af dlopen-koden. Derefter starter vi vores program inde i hovedmetoden. Her definerer vi strengen med erklæringen af ​​variablen 'src'. Vi erklærer derefter pointervariablerne 'strlen', 'handle' og 'fejl'.

Dernæst kalder vi handlevariablen og implementerer dlopen-funktionen. Funktionen dlopen indlæser det delte bibliotek 'libstr.so' til strenghåndteringsfunktioner og flaget 'RTLD_LAZY', som allerede er demonstreret i det foregående eksempel. Vi kalder dlerror-funktionen inde i 'fejl'-variablen for at rydde fejlen genereret af dlopen-funktionen. Hvis-andet bruges til at undersøge fejlene.

Derefter får vi strlen-funktionens adresse ved hjælp af dlsym-funktionen og verificerer fejlene, mens vi gør dette. Efter dette bruger vi printf-funktionen til at kalde strnlen-funktionen for at returnere længden af ​​den givne streng. Til sidst lukker vi det delte bibliotek med dlclose-funktionen.

#include
#include
#include
#include
int vigtigste ( ugyldig )
{
char * src = 'Hej Linux' ;
int ( * strlen ) ( konst char * ) ;
ugyldig * håndtere ;
char * fejl ;


håndtere = dlopen ( './libstr.so' , RTLD_LAZY ) ;
fejl = dlerror ( ) ;
hvis ( ! håndtere || fejl != NUL ) { printf ( 'Forsøg på at indlæse bibliotek mislykkedes! \n %s \n ' , fejl ) ;
Vend tilbage - 1 ; }

strlen = dlsym ( håndtere , 'strlen' ) ;
fejl = dlerror ( ) ;
hvis ( ! strlen || fejl == NUL ) { printf ( '%s \n ' , fejl ) ; Vend tilbage - 1 ; }

printf ( 'Længden af ​​strengen er:%d \n ' , strlen ( src ) ) ;
luk ( håndtere ) ;
Vend tilbage 0 ;
}

Vi bruger følgende kommando til udførelse af det givne program. Her bruges flaget -lstr til strenglængdefunktionen og ldl bruges til biblioteksfilen dlopen. Det kompilerede program giver længden af ​​strengen som vist i skallen:

Konklusion

Oplysningerne er givet om C-sprogets dlopen-funktion i denne artikel. Vi har en kort introduktion af dlopen-funktionen. Derefter implementerede vi to eksempler. Funktionen returnerer en identifikator, der definerer det åbnede bibliotek. Adresserne på funktionerne inde i det åbnede bibliotek bestemmes derefter ved hjælp af denne identifikator og dlsym-funktionen. En funktions adresse i et bibliotek, der allerede er blevet åbnet ved hjælp af dlopen, kan findes ved hjælp af dlsym-funktionen.