&reftitle.examples;
Utilisation basique de FFI
Avant de plonger dans les détails de l'API FFI, jetons un coup d'œil à quelques exemples
démontrant la simplicité d'utilisation de l'API FFI pour les tâches courantes.
Certains de ces exemples requièrent libc.so.6 et
ne fonctionneront donc pas sur les systèmes où cette bibliothèque n'est pas disponible.
Appel d'une fonction à partir d'une bibliothèque partagée
printf("Hello %s!\n", "world");
?>
]]>
&example.outputs;
Notez que certaines fonctions C nécessitent des conventions d'appel spécifiques, par exemple __fastcall,
__stdcall ou ,__vectorcall.
Appel d'une fonction, retournant une structure par l'intermédiaire d'un argument
new("struct timeval");
$tz = $ffi->new("struct timezone");
// appelle la fonction gettimeofday() de C
var_dump($ffi->gettimeofday(FFI::addr($tv), FFI::addr($tz)));
// accède au champs de la structure de données C
var_dump($tv->tv_sec);
// imprime toute la structure de données C
var_dump($tz);
?>
]]>
&example.outputs.similar;
int(0)
["tz_dsttime"]=>
int(0)
}
]]>
Accès aux variables C existantes
errno);
?>
]]>
&example.outputs;
Création et modification de variables C
cdata);
// affectation simple
$x->cdata = 5;
var_dump($x->cdata);
// affectation composée
$x->cdata += 2;
var_dump($x->cdata);
?>
]]>
&example.outputs;
Travailler avec des tableaux C
]]>
&example.outputs;
Travailler avec des enums en C
ZEND_FFI_SYM_TYPE);
var_dump($a->ZEND_FFI_SYM_CONST);
var_dump($a->ZEND_FFI_SYM_VAR);
?>
]]>
&example.outputs;
Fonctions de rappels
Il est possible d'assigner une fermeture PHP à une variable native de type pointeur de fonction
ou de la passer comme argument de fonction :
Assignation d'une Closure PHP à un pointeur de fonction C
zend_write;
$zend->zend_write = function($str, $len) {
global $orig_zend_write;
$orig_zend_write("{\n\t", 3);
$ret = $orig_zend_write($str, $len);
$orig_zend_write("}\n", 2);
return $ret;
};
echo "Hello World 2!\n";
$zend->zend_write = $orig_zend_write;
echo "Hello World 3!\n";
?>
]]>
&example.outputs;
Bien que cela fonctionne, cette fonctionnalité n'est pas supportée par toutes les plateformes libffi, n'est pas efficace
et entraîne des fuites de ressources à la fin de la requête.
Il est donc recommandé de minimiser l'utilisation des fonctions de rappels PHP.
Un exemple complet de PHP/FFI/preloading
php.ini
preload.php
]]>
dummy.h
dummy.php
printf($format, ...$args);
}
}
?>
]]>
test.php
printf("Hello %s!\n", "world");
?>
]]>