&reftitle.examples;
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.
Some of these examples require libc.so.6 and as such will
not work on systems where it is not available.
Calling a function from shared library
printf("Hello %s!\n", "world");
?>
]]>
&example.outputs;
Note that some C functions need specific calling conventions, e.g. __fastcall,
__stdcall or ,__vectorcall.
Calling a function, returning a structure through an argument
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 structure
var_dump($tv->tv_sec);
// print the whole C data structure
var_dump($tz);
?>
]]>
&example.outputs.similar;
int(0)
["tz_dsttime"]=>
int(0)
}
]]>
Accessing existing C variables
errno);
?>
]]>
&example.outputs;
Creating and Modifying C variables
cdata);
// simple assignment
$x->cdata = 5;
var_dump($x->cdata);
// compound assignment
$x->cdata += 2;
var_dump($x->cdata);
?>
]]>
&example.outputs;
Working with C arrays
]]>
&example.outputs;
Working with C enums
ZEND_FFI_SYM_TYPE);
var_dump($a->ZEND_FFI_SYM_CONST);
var_dump($a->ZEND_FFI_SYM_VAR);
?>
]]>
&example.outputs;
PHP Callbacks
It is possible to assign a PHP closure to a native variable of function pointer type
or to pass it as a function argument:
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;
Although this works, this functionality is not supported on all libffi platforms, is not efficient
and leaks resources by the end of request.
It is therefore recommended to minimize the usage of PHP callbacks.
A Complete PHP/FFI/preloading Example
php.ini
preload.php
]]>
dummy.h
dummy.php
printf($format, ...$args);
}
}
?>
]]>
test.php
printf("Hello %s!\n", "world");
?>
]]>