Linux Dlopen System i C

Linux Dlopen System I C



Biblioteksfunktionen dlopen() är en mycket användbar funktion i C-språket. Funktionen laddar biblioteket i minnet efter att ett nytt öppnats. Vi använder det vanligtvis för att ladda bibliotekssymboler som är okända vid kompileringstillfället. Dlopen() är en funktion som används i våra program. DL-biblioteket implementerar dlopen(), definierat i Dlfcn.h. Två parametrar krävs för dlopen-funktionen: namnet på biblioteksfilen och flaggan. Filens namn är ett dynamiskt bibliotek och det definierar om bibliotekets beroenden beräknas direkt. Dlopen() returnerar ett 'handtag' som bör betraktas som ett ogenomskinligt värde och andra DL-biblioteksoperationer använder detta. Om försöket att ladda misslyckas, returnerar dlopen() NULL. Men dlopen() returnerar samma filhandtag om den laddar samma bibliotek många gånger.

När kompilatorn använder dlopen-funktionen undersöker inte kompilatorn för potentiella fel eftersom den är omedveten om de typer och prototyper som vi använder. Utplaceringen av dlopen-funktionen för standardlastning verkar inte främjas av den, förutom i några mindre situationer. Förresten, det är ett tillvägagångssätt för att förbättra introspektion. När den delade modulen för närvarande används av ett annat program, är minneslayoutoptimeringen inte särskilt intresserad av villkorlig laddning. Minnesavtrycket ökar inte när ett tidigare använt bibliotek laddas. Att undvika kompilatorövervakningen är farligt och ger bra felskrivning. Dessutom saknar vi möjlig kompilatoroptimering.

Exempel 1:

Tänk nu på följande exempel för att se funktionaliteten för dlopen-funktionen i C-språket. I det första steget laddar vi några C-standardbibliotek. Här laddar vi det nya biblioteket 'dlfcn.h' som används för att definiera makron samtidigt som vi konstruerar argumentet dlopen-läge.







Sedan introducerar vi ett annat bibliotek i vårt program 'gnu/lib-name.h'. De delade biblioteksfilerna som ingår i GNU libc hittas av användarprogrammen enligt de makron som definieras. GNU C-biblioteket erbjuder de grundläggande biblioteken för operativsystemen GNU och GNU/Linux samt ett brett utbud av andra Linux-baserade system. Efter det har vi den huvudsakliga metodimplementeringen. Inuti det förklarar vi pekarobjektet 'handle' med nyckelordet void. Vi deklarerar en pekarsinusfunktion som har datatypen dubbel. Det finns en annan deklaration av pekarobjektet 'fel' för felhantering.



Efter det anropar vi dlopen-funktionen inuti 'handtag'-objektet. Dlopen tar två argument: LIBM_SO och 'RTLD_LAZY'. Här är 'LIBM_SO' namnet på biblioteksfilen som tillhandahåller matematiska funktioner som trigonometriska funktioner. Detta delade bibliotek krävs eftersom vi använder sinusfunktionen. 'RTLD_LAZY' är ett annat argument som anropar dlopen-funktionen. När en given symbol refereras första gången måste omplaceringar utföras vid en tidpunkt som bestäms av implementeringen.



Eftersom en process kanske inte refererar till varje symbol i en körbar objektfil, bör specificering av RTLD LAZY förbättra prestandan på implementeringar som möjliggör den dynamiska symbolbindningen. Därefter har vi ett if-else-villkor för felhantering när handtagsobjektet misslyckas med att utföra dlopen-funktionen. Vi ringer till dlerror för att åtgärda felet.





Funktionen dlerror() tillhandahåller en noll-terminerad sträng som är läsbar för människor och specificerar rapporteringen av det senaste felet som orsakas av ett anrop till ett av dlopen API-anrop sedan det senaste dlerror-anropet. Sedan kastar vi funktionen så här: '(*void**)(&sine)= dlsym(handle, sin)'. Eftersom detta är konstigt följer casting ISO C vilket undviker varningar från kompilatorn. Vi använder funktionen dlsym som får sökvägen till en symbol som specificeras inuti en dynamisk länkmodul som är tillgänglig via en dlopen() funktion.

Dessutom utför vi if-else-operationen igen för standardfelet som genereras när dlerror() inte är NULL. Sedan har vi en printf-sats där vi anger det sinusvärde som ska beräknas. I det sista steget stänger vi det delade objektet genom att anropa dlclose för handtaget som returneras av dlopen().



#include
#include
#include
#include

int
huvud ( int argc , röding ** argv )
{
tomhet * hantera ;
dubbel ( * deras ) ( dubbel ) ;
röding * fel ;

hantera = dlopen ( LIBM_SO , RTLD_LAZY ) ;
om ( ! hantera ) {
fprintf ( stderr , '%s \n ' , dlerror ( ) ) ;
utgång ( EXIT_FAILURE ) ;
}
dlerror ( ) ;

* ( tomhet ** ) ( & deras ) = dlsym ( hantera , 'utan' ) ;

om ( ( fel = dlerror ( ) ) != NULL ) {
fprintf ( stderr , '%s \n ' , fel ) ;
utgång ( EXIT_FAILURE ) ;
}

printf ( '%f \n ' , ( * deras ) ( 4.0 ) ) ;
dlclose ( hantera ) ;
utgång ( EXIT_SUCCESS ) ;
}

Vi använder alternativet -ldl med C-kompileringskommandot eftersom detta är biblioteket för det länkade dlopen-gränssnittet och det krävs. När exekveringen av dlopen-filen är gjord, visar den sinusvärdet för det tidigare angivna värdet.

Exempel 2:

Nu tar vi ett annat exempel på att använda dlopen-funktionen. Vi laddar vårt program med alla nödvändiga C-bibliotek för implementering av dlopen-koden. Sedan startar vi vårt program i huvudmetoden. Här definierar vi strängen med deklarationen av variabeln 'src'. Vi förklarar sedan pekarvariablerna 'strlen', 'handle' och 'error'.

Därefter anropar vi handtagsvariabeln och distribuerar dlopen-funktionen. Funktionen dlopen matar in det delade biblioteket 'libstr.so' för stränghanteringsfunktioner och flaggan 'RTLD_LAZY' som redan demonstreras i föregående exempel. Vi anropar dlerror-funktionen inuti 'error'-variabeln för att rensa felet som genereras av dlopen-funktionen. Om-annat används för att undersöka felen.

Sedan får vi strlen-funktionens adress med hjälp av dlsym-funktionen och verifierar felen medan vi gör detta. Efter detta använder vi printf-funktionen för att anropa strnlen-funktionen för att returnera längden på den givna strängen. Till slut stänger vi det delade biblioteket med funktionen dlclose.

#include
#include
#include
#include
int huvud ( tomhet )
{
röding * src = 'Hej Linux' ;
int ( * strlen ) ( konst röding * ) ;
tomhet * hantera ;
röding * fel ;


hantera = dlopen ( './libstr.so' , RTLD_LAZY ) ;
fel = dlerror ( ) ;
om ( ! hantera || fel != NULL ) { printf ( 'Försöket att ladda biblioteket misslyckades! \n %s \n ' , fel ) ;
lämna tillbaka - 1 ; }

strlen = dlsym ( hantera , 'strlen' ) ;
fel = dlerror ( ) ;
om ( ! strlen || fel == NULL ) { printf ( '%s \n ' , fel ) ; lämna tillbaka - 1 ; }

printf ( 'Längden på strängen är:%d \n ' , strlen ( src ) ) ;
dlclose ( hantera ) ;
lämna tillbaka 0 ;
}

Vi använder följande kommando för att köra det givna programmet. Här används flaggan -lstr för stränglängdsfunktionen och ldl används för biblioteksfilen dlopen. Det kompilerade programmet ger längden på strängen som visas i skalet:

Slutsats

Informationen tillhandahålls om C-språkets dlopen-funktion i den här artikeln. Vi har en kort introduktion av dlopen-funktionen. Sedan implementerade vi två exempel. Funktionen returnerar en identifierare som definierar det öppnade biblioteket. Adresserna för funktionerna i det öppnade biblioteket bestäms sedan med hjälp av denna identifierare och dlsym-funktionen. En funktions adress i ett bibliotek som redan har öppnats med dlopen kan hittas med dlsym-funktionen.