Linux Dlopen rendszer C-ben

Linux Dlopen Rendszer C Ben



A dlopen() könyvtárfüggvény nagyon hasznos függvény a C nyelvben. A függvény egy új megnyitása után betölti a könyvtárat a memóriába. Általában arra használjuk, hogy betöltsük azokat a könyvtári szimbólumokat, amelyek a fordítási időben ismeretlenek. A Dlopen() a programjainkban használt függvény. A DL könyvtár a Dlfcn.h-ban definiált dlopen() függvényt valósítja meg. A dlopen függvényhez két paraméter szükséges: a könyvtárfájl neve és a zászló. A fájl neve egy dinamikus könyvtár, és ez határozza meg, hogy a programkönyvtár függőségeit azonnal kiszámolja-e vagy sem. A dlopen() egy „handle”-t ad vissza, amelyet átlátszatlan értéknek kell tekinteni, és más DL-könyvtári műveletek ezt használják. Ha a betöltési kísérlet sikertelen, a dlopen() NULL-t ad vissza. De a dlopen() ugyanazt a fájlleírót adja vissza, ha többször betölti ugyanazt a könyvtárat.

A dlopen függvény használata közben a fordító nem vizsgálja a lehetséges hibákat, mivel nincs tisztában az általunk használt típusokkal és prototípusokkal. Úgy tűnik, hogy a dlopen funkció szabványos betöltésre történő telepítését nem támogatja, kivéve néhány kisebb helyzetet. Mellesleg, ez egy megközelítés az önvizsgálat javítására. Ha a megosztott modult éppen egy másik program használja, a memóriaelrendezés optimalizálása nem különösebben érdekli a feltételes betöltést. A memóriaterület nem növekszik egy korábban használt könyvtár betöltésekor. A fordító figyelésének elkerülése veszélyes, és jó hibaírást tesz lehetővé. Ezenkívül hiányzik a lehetséges fordítóoptimalizálás.

1. példa:

Most nézzük meg a következő példát a dlopen függvény működésének megismeréséhez a C nyelvben. Első lépésben betöltünk néhány C szabványos könyvtárat. Itt betöltjük az új „dlfcn.h” könyvtárat, amely a makrók meghatározására szolgál a dlopen mód argumentumának létrehozása során.







Ezután bemutatunk egy másik könyvtárat a „gnu/lib-name.h” programunkon belül. A GNU libc-hez tartozó megosztott könyvtár fájlokat a felhasználói programok az általa meghatározott makróknak megfelelően találják meg. A GNU C Library az alapvető könyvtárakat kínálja a GNU és GNU/Linux operációs rendszerekhez, valamint számos egyéb Linux-alapú rendszerhez. Ezt követően megvan a fő módszer megvalósítása. Ezen belül a mutatóobjektumot a void kulcsszóval „handle”-nek nyilvánítjuk. Egy mutatószinuszfüggvényt deklarálunk, amelynek adattípusa double. Van egy másik deklaráció a mutatóobjektum „hiba”-ról a hibakezeléshez.



Ezt követően meghívjuk a dlopen függvényt a „handle” objektumon belül. A dlopen két argumentumot használ: LIBM_SO és „RTLD_LAZY”. Itt a „LIBM_SO” annak a könyvtárfájlnak a neve, amely matematikai függvényeket, például trigonometrikus függvényeket biztosít. Erre a megosztott könyvtárra szükség van, mivel a szinuszfüggvényt használjuk. Az „RTLD_LAZY” egy másik argumentum, amely a dlopen függvényt hívja meg. Amikor egy adott szimbólumra először hivatkoznak, az áthelyezéseket a megvalósítás által meghatározott időpontban kell végrehajtani.



Mivel előfordulhat, hogy egy folyamat nem hivatkozik minden szimbólumra egy végrehajtható objektumfájlban, az RTLD LAZY megadása javítja a dinamikus szimbólum-összerendelést lehetővé tevő megvalósítások teljesítményét. Ezután van egy if-else feltételünk a hibakezeléshez, amikor a kezelőobjektum nem hajtja végre a dlopen funkciót. Hívjuk a dlerrort, hogy töröljük a hibát.





A dlerror() függvény egy null-végű karakterláncot biztosít, amely ember által olvasható, és meghatározza a legutóbbi hiba jelentését, amelyet a legutóbbi dlerror hívás óta valamelyik dlopen API hívás okoz. Ezután a következőképpen öntjük a függvényt: „(*void**)(&sine)= dlsym(handle, sin)”. Mivel ez furcsa, az öntés megfelel az ISO C szabványnak, amely elkerüli a fordító figyelmeztetését. A dlsym függvényt használjuk, amely egy dinamikus kapcsolati modulban megadott szimbólum elérési útját kapja meg, amely a dlopen() függvényen keresztül érhető el.

Ezenkívül ismét végrehajtjuk az if-else műveletet a standard hiba esetén, amely akkor jön létre, ha a dlerror() nem NULL. Ezután van egy printf utasításunk, ahol megadjuk a kiszámítandó szinuszértéket. Az utolsó lépésben bezárjuk a megosztott objektumot a dlclose meghívásával a dlopen() által visszaadott kezelőhöz.



#include
#include
#include
#include

int
fő- ( int argc , char ** argv )
{
üres * fogantyú ;
kettős ( * övék ) ( kettős ) ;
char * hiba ;

fogantyú = dlopen ( LIBM_SO , RTLD_LUSTA ) ;
ha ( ! fogantyú ) {
fprintf ( stderr , '%s \n ' , dlerror ( ) ) ;
kijárat ( EXIT_FAILURE ) ;
}
dlerror ( ) ;

* ( üres ** ) ( & övék ) = dlsym ( fogantyú , 'nélkül' ) ;

ha ( ( hiba = dlerror ( ) ) != NULLA ) {
fprintf ( stderr , '%s \n ' , hiba ) ;
kijárat ( EXIT_FAILURE ) ;
}

printf ( '%f \n ' , ( * övék ) ( 4.0 ) ) ;
dlclose ( fogantyú ) ;
kijárat ( EXIT_SUCCESS ) ;
}

A -ldl kapcsolót használjuk a C fordítási paranccsal, mivel ez a dlopen csatolt felület könyvtára, és ez szükséges. Amikor a dlopen fájl végrehajtásra kerül, az előzőleg megadott érték szinuszértékét jeleníti meg.

2. példa:

Most veszünk egy másik példát a dlopen függvény használatára. A programunkat betöltjük az összes szükséges C könyvtárral a dlopen kód megvalósításához. Ezután elindítjuk a programunkat a fő metóduson belül. Itt definiáljuk a karakterláncot az „src” változó deklarációjával. Ezután deklaráljuk az „strlen”, „handle” és „error” mutatóváltozókat.

Ezután meghívjuk a kezelő változót, és telepítjük a dlopen függvényt. A dlopen függvény beírja a „libstr.so” megosztott könyvtárat a karakterlánc-kezelő függvényekhez és az „RTLD_LAZY” jelzőt, amelyet az előző példában már bemutattunk. Meghívjuk a dlerror függvényt az „error” változóban, hogy töröljük a dlopen függvény által generált hibát. Az if-else a hibák vizsgálatára szolgál.

Ezután a dlsym függvény segítségével megkapjuk az strlen függvény címét, és ennek során ellenőrizzük a hibákat. Ezek után a printf függvénnyel meghívjuk az strnlen függvényt, hogy visszaadjuk az adott karakterlánc hosszát. Végül bezárjuk a megosztott könyvtárat a dlclose függvénnyel.

#include
#include
#include
#include
int fő- ( üres )
{
char * src = 'Hello Linux' ;
int ( * strlen ) ( const char * ) ;
üres * fogantyú ;
char * hiba ;


fogantyú = dlopen ( './libstr.so' , RTLD_LUSTA ) ;
hiba = dlerror ( ) ;
ha ( ! fogantyú || hiba != NULLA ) { printf ( 'A könyvtár betöltése nem sikerült! \n %s \n ' , hiba ) ;
Visszatérés - 1 ; }

strlen = dlsym ( fogantyú , 'strlen' ) ;
hiba = dlerror ( ) ;
ha ( ! strlen || hiba == NULLA ) { printf ( '%s \n ' , hiba ) ; Visszatérés - 1 ; }

printf ( 'A karakterlánc hossza:%d \n ' , strlen ( src ) ) ;
dlclose ( fogantyú ) ;
Visszatérés 0 ;
}

Az adott program végrehajtásához a következő parancsot használjuk. Itt az -lstr kapcsolót a karakterlánchossz függvényhez, az ldl-t pedig a dlopen könyvtárfájlhoz használjuk. A lefordított program megadja a karakterlánc hosszát a shellben látható módon:

Következtetés

Ebben a cikkben a C nyelv dlopen funkciójával kapcsolatos információkat közöljük. Röviden bemutatjuk a dlopen függvényt. Ezután két példát valósítottunk meg. A függvény egy azonosítót ad vissza, amely meghatározza a megnyitott könyvtárat. A megnyitott könyvtáron belüli függvények címei ezután ennek az azonosítónak és a dlsym függvénynek a segítségével kerülnek meghatározásra. A dlopen segítségével már megnyitott függvények címe a dlsym függvény segítségével található meg.