L'extension FFI (Interface de fonction étrangère) de PHP nous permet d'appeler les fonctions du langage C et les structures de données directement dans PHP, ce qui est très utile pour gérer les scénarios d'interaction sensibles aux performances ou sous-jacents. Mais une fois que vous l'avez utilisé en profondeur, vous trouverez des "mines" cachées, telles que - que se passe-t-il si vous oubliez d'écrire une structure lors de la déclaration d'une structure dans ffi :: cdef () ?
Supposons que nous ayons une structure C simple:
typedef struct {
int x;
int y;
} Point;
Nous utilisons la Déclaration FFI :: CDEF () de PHP:
$ffi = FFI::cdef("
typedef struct {
int x;
int y;
} Point;
");
Ensuite, vous pouvez l'utiliser comme ceci:
$point = $ffi->new("Point");
$point->x = 10;
$point->y = 20;
echo "Point: ({$point->x}, {$point->y})\n";
Tout fonctionne normalement. Mais maintenant, la question est: que se passe-t-il si vous oubliez d'écrire une structure ?
Dans le langage C, le point de structure et le point sont deux espaces de noms différents. À moins que vous n'utilisiez Typedef , le point n'est pas un nom de type valide. Dans FFI :: CDEF () de PHP, la situation est légèrement différente - ses règles d'analyse sont légèrement différentes de celles du compilateur C, et la tolérance aux défauts est faible.
Par exemple, vous avez écrit une déclaration comme celle-ci:
$ffi = FFI::cdef("
typedef struct Point {
int x;
int y;
} Point;
");
$pt = $ffi->new("Point");
Ce code est ok. Mais si vous manquez sans soin la partie typedef , par exemple:
$ffi = FFI::cdef("
struct Point {
int x;
int y;
};
");
$pt = $ffi->new("Point"); // Une erreur s'est produite
Ici $ ffi-> new ("Point") lancera une exception, ce qui invite au fait que le type "point" ne peut pas être trouvé. Parce qu'à ce moment, "point" est un point de structure , pas un alias de type séparé.
L'appel correct doit être:
$pt = $ffi->new("struct Point");
C'est le piège dans lequel beaucoup de gens tombent: ils pensent qu'ils ont défini le nom de la structure "point", mais en fait, vous ne définissez que le "point de structure". Si vous ne faites pas de typedef, vous ne pouvez pas utiliser le point directement.
Si vous voyez une erreur comme celle suivante:
FFI\Exception: undefined C type 'Point'
Ensuite, vous devez d'abord vérifier comment vous le déclarez dans CDEF () . Vous venez d'écrire Struct Point sans Typedef? Si c'est le cas, vous ne pouvez utiliser que Struct Point to Reference.
Une technique de débogage consiste à imprimer votre déclaration CDEF () pour vérifier si la structure a TypeDEF, par exemple:
echo $ffi->cdef;
Bien que cette méthode ne fonctionne pas toujours (en particulier dans certaines versions de PHP), elle peut vous aider à confirmer que le type est correctement enregistré.
Pour éviter la confusion, il est recommandé d'apporter Typedef dans toutes les déclarations structurelles. Par exemple:
typedef struct {
int x;
int y;
} Point;
De cette façon, vous pouvez joyeusement écrire $ ffi-> nouveau ("point") dans PHP, et ne plus vous soucier de l'ajout de préfixe struct .
Supposons que vous définissiez une structure qui niche une autre structure:
typedef struct {
int x;
int y;
} Point;
typedef struct {
Point start;
Point end;
} Line;
Ffi :: cdef () en php doit être écrit comme ceci:
$ffi = FFI::cdef("
typedef struct {
int x;
int y;
} Point;
typedef struct {
Point start;
Point end;
} Line;
");
Ensuite, vous pouvez l'utiliser comme ceci:
$line = $ffi->new("Line");
$line->start->x = 1;
$line->start->y = 2;
$line->end->x = 10;
$line->end->y = 20;
echo "Start: ({$line->start->x}, {$line->start->y})\n";
echo "End: ({$line->end->x}, {$line->end->y})\n";
Si vous manquez Typedef dans la déclaration, comme Point n'a pas de typedef, la définition de la ligne rapportera une erreur car elle ne peut pas trouver le type de point .
Lorsque vous appelez la structure de C à l'aide de PHP FFI, assurez-vous de faire attention aux points suivants:
Si la structure n'est pas typedef, le nom de type doit être préfixé avec structure
Il est recommandé que toutes les structures utilisent les déclarations de typeSEF pour éviter de nommer la confusion
Lors du débogage, j'ai rencontré une erreur de type non définie. Vérifiez d'abord si les déclarations de CDEF sont cohérentes.
Grâce à ces spécifications, vous pouvez réduire de nombreuses erreurs de type inexplicable, vous permettant de réduire les pièges et de perdre les cheveux lors de la lecture de l'interface C avec PHP.
Pour plus d'exemples sur PHP FFI, veuillez vous référer à https://gitbox.net/docs/php-ffi-exemples .