Php/docs/ffi.examples-basic

From Get docs

Basic FFI usage

Before diving into the details of the FFI API, lets take a look at a few examples demonstrating the simplicity of the FFI API usage for regular tasks.

Note:

Some of these examples require libc.so.6 and as such will not work on systems where it is not available.

Example #1 Calling a function from shared library

<?php// create FFI object, loading libc and exporting function printf()$ffi = FFI::cdef(    "int printf(const char *format, ...);", // this is a regular C declaration    "libc.so.6");// call C's printf()$ffi->printf("Hello %s!\n", "world");?>

The above example will output:


Hello world!

Note:

Note that some C functions need specific calling conventions, e.g. __fastcall, __stdcall or ,__vectorcall.

Example #2 Calling a function, returning a structure through an argument

<?php// create gettimeofday() binding$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");// create C data structures$tv = $ffi->new("struct timeval");$tz = $ffi->new("struct timezone");// call C's gettimeofday()var_dump($ffi->gettimeofday(FFI::addr($tv), FFI::addr($tz)));// access field of C data structurevar_dump($tv->tv_sec);// print the whole C data structurevar_dump($tz);?>

The above example will output something similar to:


int(0)
int(1555946835)
object(FFI\CData:struct timezone)#3 (2) {
  ["tz_minuteswest"]=>
  int(0)
  ["tz_dsttime"]=>
  int(0)
}

Example #3 Accessing existing C variables

<?php// create FFI object, loading libc and exporting errno variable$ffi = FFI::cdef(    "int errno;", // this is a regular C declaration    "libc.so.6");// print C's errnovar_dump($ffi->errno);?>

The above example will output:


int(0)

Example #4 Creating and Modifying C variables

<?php// create a new C int variable$x = FFI::new("int");var_dump($x->cdata);// simple assignment$x->cdata = 5;var_dump($x->cdata);// compound assignment$x->cdata += 2;var_dump($x->cdata);?>

The above example will output:


int(0)
int(5)
int(7)

Example #5 Working with C arrays

<?php// create C data structure$a = FFI::new("long[1024]");// work with it like with a regular PHP arrayfor ($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));?>

The above example will output:


int(25)
int(523776)
int(1024)
int(8192)

Example #6 Working with C enums

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

The above example will output:


int(0)
int(2)
int(3)