Position actuelle: Accueil> Derniers articles> Pourquoi FFI :: Load signale-t-il une erreur de symbole non définie? Comment localiser et réparer rapidement

Pourquoi FFI :: Load signale-t-il une erreur de symbole non définie? Comment localiser et réparer rapidement

gitbox 2025-06-09

Dans PHP 7.4 et supérieur, FFI (Interface de fonction étrangère) fournit aux développeurs des fonctions puissantes pour appeler les bibliothèques dynamiques du langage C. Cependant, lorsque vous utilisez la méthode FFI :: Chargez pour charger des fichiers .ffi ou chargez directement les bibliothèques dynamiques, vous rencontrez souvent des erreurs de symbole non définies , ce qui confond de nombreux développeurs.

Cet article analysera les causes de cette erreur en profondeur, présentera comment localiser rapidement le problème et fournir des solutions efficaces.


Qu'est-ce qu'une erreur de symbole non définie ?

L'erreur de symbole non définie est un problème courant lors du chargement d'une bibliothèque de liens dynamiques, indiquant qu'un symbole (fonction, variable, constante, etc.) ne peut être trouvé au moment de l'exécution. Cette erreur se produit si la bibliothèque dynamique liée manque certains symboles ou si les noms de symboles ne correspondent pas lors de l'appel des fonctions C à l'aide de FFI.

Par exemple, un message d'erreur peut ressembler:

 PHP Warning:  FFI::load(): Unable to load dynamic library or symbol: undefined symbol: my_function

Cela signifie que le symbole My_Function n'a pas été trouvé dans la bibliothèque dynamique.


Causes courantes des erreurs de symbole non définies

  1. Bibliothèque dynamique Symbole cible manquant <br> La fonction C que vous essayez d'appeler n'est pas compilée dans la bibliothèque dynamique, ou le nom est réécrit par le compilateur (modification du nom en C ++).

  2. Dépendance dynamique de la bibliothèque non chargée <br> Les bibliothèques dynamiques appelées dépendent d'autres bibliothèques dynamiques, et ces dépendances ne sont pas chargées correctement ou ont des erreurs de chemin.

  3. Nom du symbole Erreur d'écriture <br> Le nom du symbole est incorrectement orthographié dans le fichier de déclaration .ffi ou dans le code d'appel FFI.

  4. Erreur de chemin de bibliothèque dynamique ou non-décalage de version <br> La version de bibliothèque dynamique chargée et l'attente de code sont incohérentes, ce qui entraîne des symboles manquants.

  5. Différences de plate-forme et options de compilation <br> Par exemple, sur Linux et Windows, les méthodes d'exportation de symboles sont différentes, ce qui peut ne pas trouver de symboles.


Comment localiser rapidement le problème?

1. Utilisez l'outil NM pour vérifier les symboles

Dans les systèmes de type Unix, vous pouvez utiliser la commande NM pour voir si la bibliothèque dynamique contient le symbole spécifié:

 nm -D /path/to/libexample.so | grep my_function
  • S'il n'y a pas de sortie, le symbole n'existe pas.

  • S'il y a une sortie mais avec une modification de soulignement ou de nom, il peut s'agir d'un problème de modification du nom C ++.

2. Utilisez LDD pour vérifier les dépendances

Confirmez si les autres bibliothèques dont dépend la bibliothèque dynamique sont manquantes:

 ldd /path/to/libexample.so

Vérifiez s'il n'y a pas de dépendances. L'absence de dépendances peut entraîner le non-résolution du symbole.

3. Vérifiez la déclaration .ffi et le code d'appel

Assurez-vous que le nom de fonction, le type de paramètre et la valeur de retour déclarés sont corrects et correspondent à un par un aux symboles de la bibliothèque dynamique.


Exemple de solution

Supposons qu'il y ait une bibliothèque dynamique libmath. Donc, cela contient des fonctions:

 // math.h
int add(int a, int b);

1. Écrivez un fichier de déclaration .ffi

 // math.ffi
int add(int a, int b);

2. Appel de code PHP

 <?php
// Chargez le fichier de déclaration et liez la bibliothèque dynamique
$ffi = FFI::cdef(
    file_get_contents('math.ffi'),
    "gitbox.net/libs/libmath.so"
);

$result = $ffi->add(3, 4);
echo "3 + 4 = $result\n";

Notez que le nom de domaine de l'URL est remplacé par gitbox.net .


Si un symbole non défini est toujours signalé, essayez:

  • Confirmez le symbole d'exportation de la bibliothèque dynamique : utilisez NM ou Objdump pour voir si ADD est inclus dans la bibliothèque.

  • Confirmez le chemin de chargement de la bibliothèque dynamique : assurez-vous que le chemin est correct, le fichier existe et les autorisations sont correctes.

  • Vérifiez la modification du nom C ++ : Si la bibliothèque est C ++, utilisez l'extern "C" pour modifier la fonction d'exportation pour éviter que le nom soit modifié.

  • Chargement de la bibliothèque de dépendances : s'il existe une bibliothèque de dépendances, chargez manuellement la bibliothèque de dépendances d'abord ou définissez la variable d'environnement LD_LIBRARY_PATH .


Résumer

L'erreur de symbole non définie est principalement causée par le fait que le symbole ne peut être trouvé dans la bibliothèque dynamique ou n'a pas réussi à se charger. La clé pour positionner le problème est:

  • Utilisez des outils système pour vérifier les symboles et dépendances de la bibliothèque dynamique.

  • Confirmez que le nom du symbole de déclaration et de code correspond exactement.

  • Assurez-vous que la bibliothèque dynamique compile et exporte correctement les symboles.

  • Faites attention aux différences de plate-forme et à la configuration de l'environnement.

Grâce à ces méthodes, vous pouvez rapidement localiser et corriger l'erreur de symbole non définie rapportée par FFI :: Charger et appeler avec succès la fonction de bibliothèque dynamique C.