FFI란 무엇입니까
FFI, 외국 함수 인터페이스, 외국 함수 인터페이스. 이 확장을 사용하면 일부 공용 라이브러리(.dll, .so)를 로드할 수 있으며 이는 실제로 일부 C 데이터 구조 및 함수를 호출할 수 있음을 의미합니다. 이는 이미 PHP 소스 코드와 함께 출시된 확장입니다. 컴파일할 때 --with-ffi를 추가하여 PHP 프로그램으로 직접 컴파일할 수 있습니다.
여기에는 이미 PHP가 컴파일되어 있으므로 이 확장을 직접 찾아 간단한 확장 설치 단계를 수행하여 설치를 완료합니다.
cd php-7.4.4/ext/ffi/ phpize ./configure make && make install
설치 후 php.ini 파일에서 확장 프로그램을 여는 것을 잊지 마세요. 이 확장에 대해 주목해야 할 점은 구성 항목 ffi.enable이 있다는 것입니다. 기본적으로 이 구성 항목의 값은 CLI SAPI 환경에서 FFI 기능만 활성화하는 "preload"입니다. 물론 "true" 또는 "false"로 변경하여 켜거나 끌 수도 있습니다. "true"로 설정하면 모든 환경에서 이 확장이 활성화됩니다.
FFI를 사용하여 C 함수 호출
다음으로 C 함수 호출 방법을 간략하게 살펴보겠습니다.
// 创建一个 FFI 对象,加载 libc 并且导入 printf 函数 $ffi_printf = FFI::cdef( "int printf(const char *format, ...);", // C 的定义规则 "libc.so.6"); // 指定 libc 库 // 调用 C 的 printf 函数 $ffi_printf->printf("Hello %s!\n", "world"); // Hello World // 加载 math 并且导入 pow 函数 $ffi_pow = FFI::cdef( "double pow(double x, double y);", "libboost_math_c99.so.1.66.0"); // 这里调用的是 C 的 pow 函数,不是 PHP 自己的 echo $ffi_pow->pow(2,3), PHP_EOL; // 8
우리는 두 개의 객체를 생성하고 C의 printf() 및 pow() 함수를 각각 호출했습니다. FFI::cdef()는 FFI 객체를 생성하는 데 사용됩니다. 이는 두 개의 매개변수를 받습니다. 하나는 일반 C 언어의 선언 시퀀스(유형, 구조, 함수, 변수 등)가 포함된 문자열입니다. 실제로 이 문자열은 C 헤더 파일에서 복사하여 붙여넣을 수 있습니다. 다른 매개변수는 로드하고 링크할 공유 라이브러리 파일의 이름입니다. 그것이 우리가 선언한 문자열에 해당하는 .dll 또는 .so 파일입니다. 예를 들어 libc.so.6에는 pow()와 같은 계산 함수가 없으므로 수학 관련 C를 찾아야 합니다. 언어 계산 기능 라이브러리.
변수 및 배열 정의
물론 FFI에서는 변수와 배열도 정의할 수 있습니다.
// 创建一个 int 变量 $x = FFI::new("int"); var_dump($x->cdata); // int(0) // 为变量赋值 $x->cdata = 5; var_dump($x->cdata); // int(5) // 计算变量 $x->cdata += 2; var_dump($x->cdata); // int(7) // 结合上面的两个 FFI 对象操作 echo "pow value:", $ffi_pow->pow($x->cdata, 3), PHP_EOL; // pow value:343 $ffi_printf->printf("Int Pow value is : %f\n", $ffi_pow->pow($x->cdata, 3)); // Int Pow value is : 343.000000 // 创建一个数组 $a = FFI::new("long[1024]"); // 为数组赋值 for ($i = 0; $i < count($a); $i++) { $a[$i] = $i; } var_dump($a[25]); // int(25) $sum = 0; foreach ($a as $n) { $sum += $n; } var_dump($sum); // int(523776) var_dump(count($a)); // int(1024) 数组长度 var_dump(FFI::sizeof($a)); // int(8192),内存大小
FFI::new() 함수를 사용하여 C 데이터 구조, 즉 변수 선언을 생성하면 이러한 변수의 내용이 cdata 속성에 저장됩니다. 배열은 이 함수의 반환 값에 대해 직접 작동할 수 있습니다. 물론 사용을 종료하려면 C 언어 개발과 마찬가지로 FFI::free()를 사용하여 변수를 해제해야 합니다.
요약
정말 숭고한 느낌이 들지 않나요? 그러나 FFI에서 호출하는 C 함수는 PHP 자체에서 호출하는 C 함수만큼 효율적이지 않습니다. 예를 들어, 이 pow() 함수를 사용하면 PHP 자체를 사용하는 것이 더 효율적입니다. 또한 FFI 확장은 PHP와 동시에 출시되었지만 아직 실험적입니다. 즉, 이번 확장은 향후 사용될 수 있는 다른 기능에 대비해 준비한 것으로 아직 불확실성이 많다. 따라서 프로덕션 환경에서 유사한 기능이 필요하다면 여전히 더 심층적인 조사가 필요합니다.
테스트 코드:
https://github.com/zhangyue0503/dev-blog/blob/master/php/202004/source/%E8%AE%A9PHP%E8%83%BD%E5%A4%9F%E8%B0%83%E7%94%A8C%E7%9A%84%E5%87%BD%E6%95%B0-FFI%E6%89%A9%E5%B1%95.php