## 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.

> 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)