array ( 0 => 'index.php', 1 => 'PHP Manual', ), 'head' => array ( 0 => 'UTF-8', 1 => 'fr', ), 'this' => array ( 0 => 'ffi.examples-basic.php', 1 => 'Utilisation basique de FFI', ), 'up' => array ( 0 => 'ffi.examples.php', 1 => 'Exemples', ), 'prev' => array ( 0 => 'ffi.examples.php', 1 => 'Exemples', ), 'next' => array ( 0 => 'ffi.examples-callback.php', 1 => 'Fonctions de rappels', ), 'alternatives' => array ( ), 'source' => array ( 'lang' => 'fr', 'path' => 'reference/ffi/examples.xml', ), ); $setup["toc"] = $TOC; $setup["toc_deprecated"] = $TOC_DEPRECATED; $setup["parents"] = $PARENTS; manual_setup($setup); ?>
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.
Note:
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.
Exemple #1 Appel d'une fonction à partir d'une bibliothèque partagée
<?php
// crée un objet FFI, en chargeant la libc et en exportant la fonction printf()
$ffi = FFI::cdef(
"int printf(const char *format, ...);", // Declaration C régulière
"libc.so.6");
// appele la fonction printf() de C
$ffi->printf("Hello %s!\n", "world");
?>
L'exemple ci-dessus va afficher :
Hello world!
Note:
Notez que certaines fonctions C nécessitent des conventions d'appel spécifiques, par exemple
__fastcall
,__stdcall
ou,__vectorcall
.
Exemple #2 Appel d'une fonction, retournant une structure par l'intermédiaire d'un argument
<?php
// crée la liaison gettimeofday()
$ffi = FFI::cdef("
typedef unsigned int time_t;
typedef unsigned int suseconds_t;
struct timeval {
time_t tv_sec;
suseconds_t tv_usec;
};
struct timezone {
int tz_minuteswest;
int tz_dsttime;
};
int gettimeofday(struct timeval *tv, struct timezone *tz);
", "libc.so.6");
// crée les structures de données C
$tv = $ffi->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);
?>
Résultat de l'exemple ci-dessus est similaire à :
int(0) int(1555946835) object(FFI\CData:struct timezone)#3 (2) { ["tz_minuteswest"]=> int(0) ["tz_dsttime"]=> int(0) }
Exemple #3 Accès aux variables C existantes
<?php
// crée un objet FFI, en chargeant la libc et en exportant la variable errno
$ffi = FFI::cdef(
"int errno;", // Declaration C régulière
"libc.so.6");
// imprime la valeur errno de C
var_dump($ffi->errno);
?>
L'exemple ci-dessus va afficher :
int(0)
Exemple #4 Création et modification de variables C
<?php
// crée une nouvelle variable C de type int
$x = FFI::new("int");
var_dump($x->cdata);
// affectation simple
$x->cdata = 5;
var_dump($x->cdata);
// affectation composée
$x->cdata += 2;
var_dump($x->cdata);
?>
L'exemple ci-dessus va afficher :
int(0) int(5) int(7)
Exemple #5 Travailler avec des tableaux C
<?php
// crée une structure de données en C
$a = FFI::new("long[1024]");
// modification de la structure comme avec un tableau PHP normal
for ($i = 0; $i < count($a); $i++) {
$a[$i] = $i;
}
var_dump($a[25]);
$sum = 0;
foreach ($a as $n) {
$sum += $n;
}
var_dump($sum);
var_dump(count($a));
var_dump(FFI::sizeof($a));
?>
L'exemple ci-dessus va afficher :
int(25) int(523776) int(1024) int(8192)
Exemple #6 Travailler avec des enums en C
<?php
$a = FFI::cdef('typedef enum _zend_ffi_symbol_kind {
ZEND_FFI_SYM_TYPE,
ZEND_FFI_SYM_CONST = 2,
ZEND_FFI_SYM_VAR,
ZEND_FFI_SYM_FUNC
} zend_ffi_symbol_kind;
');
var_dump($a->ZEND_FFI_SYM_TYPE);
var_dump($a->ZEND_FFI_SYM_CONST);
var_dump($a->ZEND_FFI_SYM_VAR);
?>
L'exemple ci-dessus va afficher :
int(0) int(2) int(3)