기본 FFI 사용

FFI API의 세부 사항을 살펴보기 전에 일반 작업에 대한 FFI API 사용의 단순성을 보여주는 몇 가지 예를 살펴보겠습니다.

메모: 이러한 예 중 일부는 libc.so.6이 필요하므로 사용할 수 없는 시스템에서는 작동하지 않습니다.

예제 #1 공유 라이브러리에서 함수 호출

                  
<?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!
                

메모: 일부 C 함수에는 특정 호출 규칙이 필요합니다. __fastcall, __stdcall 또는 ,__vectorcall.

예제 #2 함수 호출, 인수를 통해 구조 반환

                  
<?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 기존 C 변수 액세스

                  
<?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 C 변수 생성 및 수정

                  
<?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 C 배열 작업

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

예제 #6 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);
?>
                  
                

위의 예는 다음을 출력합니다.

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