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.

Пример #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!

Пример #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 structure
var_dump($tv->tv_sec);
// print the whole C data structure
var_dump($tz);
?>

Результатом выполнения данного примера будет что-то подобное:

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

Пример #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 errno
var_dump($ffi->errno);
?>

Результат выполнения данного примера:

int(0)

Пример #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)

Пример #5 Working with C arrays

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

Результат выполнения данного примера:

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