Linux-Dlopen-System in C

Linux Dlopen System In C



Die Bibliotheksfunktion dlopen() ist eine sehr nützliche Funktion in der Sprache C. Die Funktion lädt die Bibliothek nach dem Öffnen einer neuen in den Speicher. Wir verwenden es im Allgemeinen, um die Bibliothekssymbole zu laden, die zur Kompilierzeit unbekannt sind. Dlopen() ist eine Funktion, die in unseren Programmen verwendet wird. Die DL-Bibliothek implementiert dlopen(), definiert in Dlfcn.h. Für die dlopen-Funktion werden zwei Parameter benötigt: der Name der Bibliotheksdatei und das Flag. Der Name der Datei ist eine dynamische Bibliothek und definiert, ob die Abhängigkeiten der Bibliothek sofort berechnet werden oder nicht. dlopen() gibt ein „Handle“ zurück, das als undurchsichtiger Wert betrachtet werden sollte, und andere DL-Bibliotheksoperationen verwenden dies. Wenn der Ladeversuch nicht erfolgreich ist, gibt dlopen() NULL zurück. Aber dlopen() gibt das gleiche Datei-Handle zurück, wenn es die gleiche Bibliothek viele Male lädt.

Bei der Verwendung der dlopen-Funktion prüft der Compiler nicht auf mögliche Fehler, da er die von uns verwendeten Typen und Prototypen nicht kennt. Der Einsatz der dlopen-Funktion für das Standardladen scheint davon abgesehen von einigen geringfügigen Situationen nicht gefördert zu werden. Übrigens ist es ein Ansatz zur Verbesserung der Selbstbeobachtung. Wenn das gemeinsam genutzte Modul gerade von einem anderen Programm verwendet wird, ist die Speicherlayoutoptimierung nicht besonders am bedingten Laden interessiert. Der Speicherbedarf erhöht sich nicht, wenn eine zuvor verwendete Bibliothek geladen wird. Das Vermeiden der Compiler-Überwachung ist gefährlich und sorgt für gutes Fehlerschreiben. Außerdem fehlt uns die mögliche Compiler-Optimierung.

Beispiel 1:

Betrachten Sie nun das folgende Beispiel, um die Funktionalität der Funktion dlopen in der Sprache C zu sehen. Im ersten Schritt laden wir einige C-Standardbibliotheken. Hier laden wir die neue Bibliothek „dlfcn.h“, die verwendet wird, um die Makros zu definieren, während das Argument für den dlopen-Modus erstellt wird.







Dann führen wir eine weitere Bibliothek in unserem Programm „gnu/lib-name.h“ ein. Die in GNU libc enthaltenen gemeinsam genutzten Bibliotheksdateien werden von den Benutzerprogrammen gemäß den von ihr definierten Makros gefunden. Die GNU C Library bietet die grundlegenden Bibliotheken für die Betriebssysteme GNU und GNU/Linux sowie eine breite Palette anderer Linux-basierter Systeme. Danach haben wir die Implementierung der Hauptmethode. Darin deklarieren wir das Zeigerobjekt „handle“ mit dem Schlüsselwort void. Wir deklarieren eine Zeiger-Sinus-Funktion, die den Datentyp Double hat. Zur Fehlerbehandlung gibt es eine weitere Deklaration des Pointer-Objekts „error“.



Danach rufen wir die dlopen-Funktion innerhalb des „handle“-Objekts auf. Das dlopen akzeptiert zwei Argumente: LIBM_SO und „RTLD_LAZY“. Hier ist „LIBM_SO“ der Name der Bibliotheksdatei, die mathematische Funktionen wie trigonometrische Funktionen bereitstellt. Diese gemeinsam genutzte Bibliothek ist erforderlich, da wir die Sinusfunktion verwenden. „RTLD_LAZY“ ist ein weiteres Argument, das die dlopen-Funktion aufruft. Wenn ein bestimmtes Symbol zum ersten Mal referenziert wird, müssen Verschiebungen zu einem durch die Implementierung bestimmten Zeitpunkt durchgeführt werden.



Da ein Prozess möglicherweise nicht auf jedes Symbol in einer ausführbaren Objektdatei verweist, sollte die Angabe von RTLD LAZY die Leistung bei Implementierungen verbessern, die die dynamische Symbolbindung ermöglichen. Als nächstes haben wir eine if-else-Bedingung für die Fehlerbehandlung, wenn das Handle-Objekt die dlopen-Funktion nicht ausführen kann. Wir rufen dlerror auf, um den Fehler zu löschen.





Die dlerror()-Funktion stellt eine nullterminierte Zeichenfolge bereit, die für Menschen lesbar ist und die Meldung des letzten Fehlers angibt, der durch einen Aufruf an einen der dlopen-API-Aufrufe seit dem letzten dlerror-Aufruf verursacht wurde. Dann wandeln wir die Funktion wie folgt um: „(*void**)(&sine)= dlsym(handle, sin)“. Da dies seltsam ist, entspricht das Casting ISO C, wodurch Warnungen des Compilers vermieden werden. Wir verwenden die dlsym-Funktion, die den Pfad eines Symbols erhält, das in einem dynamischen Linkmodul angegeben ist, auf das über eine dlopen()-Funktion zugegriffen werden kann.

Außerdem führen wir die if-else-Operation erneut für den Standardfehler aus, der generiert wird, wenn dlerror() nicht NULL ist. Dann haben wir eine printf-Anweisung, in der wir den zu berechnenden Sinuswert angeben. Im letzten Schritt schließen wir dieses gemeinsam genutzte Objekt, indem wir dlclose für das von dlopen() zurückgegebene Handle aufrufen.



#include
#include
#include
#include

int
hauptsächlich ( int Argc , verkohlen ** argv )
{
Leere * handhaben ;
doppelt ( * ihre ) ( doppelt ) ;
verkohlen * Error ;

handhaben = öffnen ( LIBM_SO , RTLD_LAZY ) ;
wenn ( ! handhaben ) {
fprintf ( stderr , '%s \n ' , dlerror ( ) ) ;
Ausfahrt ( EXIT_FAILURE ) ;
}
dlerror ( ) ;

* ( Leere ** ) ( & ihre ) = dlsym ( handhaben , 'ohne' ) ;

wenn ( ( Error = dlerror ( ) ) != NULL ) {
fprintf ( stderr , '%s \n ' , Error ) ;
Ausfahrt ( EXIT_FAILURE ) ;
}

Druckf ( '%f \n ' , ( * ihre ) ( 4.0 ) ) ;
schließen ( handhaben ) ;
Ausfahrt ( EXIT_SUCCESS ) ;
}

Wir verwenden die Option -ldl mit dem C-Kompilierungsbefehl, da dies die Bibliothek für die verknüpfte dlopen-Schnittstelle ist und erforderlich ist. Wenn die Ausführung der dlopen-Datei erfolgt, zeigt sie den Sinuswert des zuvor angegebenen Werts an.

Beispiel 2:

Nun nehmen wir ein weiteres Beispiel für die Verwendung der Funktion dlopen. Wir laden unser Programm mit allen erforderlichen C-Bibliotheken für die Implementierung des dlopen-Codes. Dann starten wir unser Programm innerhalb der Hauptmethode. Hier definieren wir den String mit der Deklaration der Variablen „src“. Anschließend deklarieren wir die Pointer-Variablen „strlen“, „handle“ und „error“.

Als nächstes rufen wir die Handle-Variable auf und stellen die dlopen-Funktion bereit. Die Funktion dlopen gibt die gemeinsam genutzte Bibliothek „libstr.so“ für Funktionen zur Verarbeitung von Zeichenfolgen und das Flag „RTLD_LAZY“ ein, das bereits im vorherigen Beispiel demonstriert wurde. Wir rufen die dlerror-Funktion innerhalb der „error“-Variablen auf, um den von der dlopen-Funktion erzeugten Fehler zu löschen. Das if-else wird verwendet, um die Fehler zu untersuchen.

Dann erhalten wir die Adresse der strlen-Funktion mit der dlsym-Funktion und verifizieren dabei die Fehler. Danach verwenden wir die printf-Funktion, um die strnlen-Funktion aufzurufen, um die Länge der angegebenen Zeichenfolge zurückzugeben. Am Ende schließen wir die gemeinsam genutzte Bibliothek mit der Funktion dlclose.

#include
#include
#include
#include
int hauptsächlich ( Leere )
{
verkohlen * Quelle = 'Hallo Linux' ;
int ( * Strlen ) ( konst verkohlen * ) ;
Leere * handhaben ;
verkohlen * Error ;


handhaben = öffnen ( './libstr.so' , RTLD_LAZY ) ;
Error = dlerror ( ) ;
wenn ( ! handhaben || Error != NULL ) { Druckf ( „Versuch des Ladens der Bibliothek fehlgeschlagen! \n %s \n ' , Error ) ;
Rückkehr - 1 ; }

Strlen = dlsym ( handhaben , 'strlen' ) ;
Error = dlerror ( ) ;
wenn ( ! Strlen || Error == NULL ) { Druckf ( '%s \n ' , Error ) ; Rückkehr - 1 ; }

Druckf ( 'Die Länge des Strings ist: %d \n ' , Strlen ( Quelle ) ) ;
schließen ( handhaben ) ;
Rückkehr 0 ;
}

Wir verwenden den folgenden Befehl für die Ausführung des angegebenen Programms. Hier wird das Flag -lstr für die Zeichenfolgenlängenfunktion und das ldl für die dlopen-Bibliotheksdatei verwendet. Das kompilierte Programm gibt die Länge der Zeichenfolge wie in der Shell angezeigt aus:

Fazit

Die Informationen zur dlopen-Funktion der C-Sprache werden in diesem Artikel bereitgestellt. Wir haben eine kurze Einführung in die Funktion dlopen. Dann haben wir zwei Beispiele implementiert. Die Funktion gibt einen Bezeichner zurück, der die geöffnete Bibliothek definiert. Anhand dieser Kennung und der Funktion dlsym werden dann die Adressen der Funktionen innerhalb der geöffneten Bibliothek ermittelt. Die Adresse einer Funktion innerhalb einer Bibliothek, die bereits mit dlopen geöffnet wurde, kann mit der Funktion dlsym gefunden werden.