In PHP 7.4 und oben bietet FFI (Fremdenfunktionsschnittstelle) Entwicklern leistungsstarke Funktionen, um C -Sprachdynamische Bibliotheken aufzurufen. Wenn Sie jedoch die FFI :: Lastmethode zum Laden von .ffi -Dateien oder direkt dynamische Bibliotheken verwenden, begegnen Sie häufig undefinierte Symbolfehler , was viele Entwickler verwirrt.
In diesem Artikel wird die Ursachen dieses Fehlers in der Tiefe analysiert, das Problem schnell lokalisiert und wirksame Lösungen bereitstellen.
Der undefinierte Symbolfehler ist ein häufiges Problem beim Laden einer dynamischen Verbindungsbibliothek, die angibt, dass ein Symbol (Funktion, Variable, Konstante usw.) nicht zur Laufzeit gefunden werden kann. Dieser Fehler tritt auf, wenn die verknüpfte dynamische Bibliothek einige Symbole fehlt oder die Symbolnamen beim Aufrufen von C -Funktionen mit FFI nicht übereinstimmen.
Beispielsweise könnte eine Fehlermeldung wie:
PHP Warning: FFI::load(): Unable to load dynamic library or symbol: undefined symbol: my_function
Dies bedeutet, dass das Symbol my_function in der dynamischen Bibliothek nicht gefunden wurde.
Dynamische Bibliothek fehlen Zielsymbol <br> Die C -Funktion, die Sie aufrufen möchten, wird nicht in die dynamische Bibliothek kompiliert, oder der Name wird vom Compiler umgeschrieben (Namensänderung in C ++).
Dynamische Bibliotheksabhängigkeit nicht geladen <br> Die bezeichneten dynamischen Bibliotheken hängen von anderen dynamischen Bibliotheken ab, und diese Abhängigkeiten werden nicht korrekt geladen oder haben Pfadfehler.
Symbolname Schreibfehler <br> Der Symbolname wird in der .ffi -Deklarationsdatei oder im FFI -Anrufcode falsch geschrieben.
Dynamischer Bibliothekspfad -Fehler oder Versionsfehlanpassung <br> Die geladene dynamische Bibliotheksversion und die Codeerwartung sind inkonsistent, was zu fehlenden Symbolen führt.
Plattformunterschiede und Kompilierungsoptionen <br> Zum Beispiel unterliegen Symbolexportmethoden unter Linux und Windows, was dazu führen kann, dass Symbole nicht gefunden werden.
In Unix-ähnlichen Systemen können Sie den Befehl nm verwenden, um festzustellen, ob die dynamische Bibliothek das angegebene Symbol enthält:
nm -D /path/to/libexample.so | grep my_function
Wenn es keine Ausgabe gibt, existiert das Symbol nicht.
Bei Ausgabe, jedoch mit Unterstrich- oder Namensänderung, kann dies ein C ++ - Name -Modifikationsproblem sein.
Bestätigen Sie, ob die anderen Bibliotheken, von denen die dynamische Bibliothek abhängt, fehlt:
ldd /path/to/libexample.so
Überprüfen Sie, ob keine Abhängigkeiten gefunden werden . Das Fehlen von Abhängigkeiten kann dazu führen, dass das Symbol ungelöst ist.
Stellen Sie sicher, dass der deklarierte Funktionsname, der Parametertyp und der Rückgabewert korrekt sind und nacheinander den Symbolen in der dynamischen Bibliothek entsprechen.
Angenommen, es gibt eine dynamische Bibliothek libmath. So enthält Funktionen:
// math.h
int add(int a, int b);
// math.ffi
int add(int a, int b);
<?php
// Laden Sie die Deklarationsdatei und verknüpfen Sie die dynamische Bibliothek
$ffi = FFI::cdef(
file_get_contents('math.ffi'),
"gitbox.net/libs/libmath.so"
);
$result = $ffi->add(3, 4);
echo "3 + 4 = $result\n";
Beachten Sie, dass der Domänenname in der URL durch gitbox.net ersetzt wird.
Bestätigen Sie das dynamische Exportsymbol der Bibliothek : Verwenden Sie NM oder OBJDUMP, um festzustellen, ob das Add in der Bibliothek enthalten ist.
Bestätigen Sie den Dynamic Library Ladepfad : Stellen Sie sicher, dass der Pfad korrekt ist, die Datei existiert und die Berechtigungen korrekt sind.
Überprüfen Sie die C ++ - Name Änderung : Wenn die Bibliothek C ++ ist, verwenden Sie extern "c" , um die Exportfunktion zu ändern, um zu vermeiden, dass der geänderte Name geändert wird.
Laden der Abhängigkeitsbibliothek : Wenn eine Abhängigkeitsbibliothek vorhanden ist, laden Sie die Abhängigkeitsbibliothek zuerst manuell oder setzen Sie die Umgebungsvariable LD_LIBRARY_PATH .
Der undefinierte Symbolfehler wird hauptsächlich durch die Tatsache verursacht, dass das Symbol in der dynamischen Bibliothek nicht gefunden werden kann oder nicht geladen wurde. Der Schlüssel zur Positionierung des Problems ist:
Verwenden Sie Systemwerkzeuge, um dynamische Bibliotheksymbole und Abhängigkeiten zu überprüfen.
Bestätigen Sie, dass der Name der Deklaration und des Codesymbols genau übereinstimmt.
Stellen Sie sicher, dass die dynamische Bibliothek Symbole richtig kompiliert und exportiert.
Achten Sie auf Plattformunterschiede und Umgebungskonfigurationen.
Mit diesen Methoden können Sie den von FFI :: Load gemeldeten undefinierten Symbolfehler schnell lokalisieren und beheben und die dynamische Bibliotheksfunktion C erfolgreich aufrufen.