Php/docs/ffi.examples-basic
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");?>
以上例程会输出:
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);?>
以上例程的输出类似于:
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);?>
以上例程会输出:
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);?>
以上例程会输出:
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));?>
以上例程会输出:
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);?>
以上例程会输出:
int(0) int(2) int(3)