PHP의 FFI (외부 기능 인터페이스) 함수를 사용하면 C 언어로 함수를 직접 호출하여 PHP의 응용 프로그램 시나리오를 크게 확장 할 수 있습니다. ffi :: cdef () 를 통해 C 언어의 함수 선언을 PHP 코드에 매핑하여 기본 효율적인 작동을 달성 할 수 있습니다.
그러나 ffi :: cdef ()를 사용할 때 일반적인 문제는 C 유형 선언이 실제 라이브러리의 유형과 일치하지 않으면 프로그램이 충돌하여 PHP 프로세스가 직접 끊을 수 있다는 것입니다. 이러한 종류의 충돌은 일반적으로 디버깅하기가 어렵고 특정 원인을 감지하기가 쉽지 않습니다.
이 기사는 예제를 결합하여 이러한 충돌 문제를 해결하고 처리하는 방법을 설명합니다.
ffi :: cdef ()는 다음과 같은 C 언어의 유형 및 함수 서명을 정의하는 데 사용됩니다.
<?php
$ffi = FFI::cdef("
int printf(const char *format, ...);
");
$ffi->printf("Hello, %s!\n", "world");
?>
이 코드는 C의 printf 함수를 PHP에 선언 한 다음 호출 할 수 있습니다.
그러한 C 라이브러리가 있다고 가정하면 함수 서명은 다음과 같습니다.
// C 언어 기능 선언
void process_data(const char *data, size_t len);
PHP에서 정의하면 다음과 같이 작성되었습니다.
<?php
$ffi = FFI::cdef("
void process_data(const char *data, int len);
");
$ffi->process_data("example", 7);
?>
C의 두 번째 매개 변수는 size_t 이며, 이는 서명되지 않은 긴 정수 (일반적으로 플랫폼에 따라 64 비트 또는 32 비트)이며 INT는 PHP로 작성됩니다. 이 유형의 불일치로 인해 매개 변수를 전달할 때 데이터가 잘립니다.
ffi :: cdef ()를 사용하는 경우 공식 또는 타사 라이브러리의 헤더 파일을 참조하여 유형 선언을 완전히 일관성있게 유지하십시오. 다음 공통 데이터 유형에 특별한주의를 기울이십시오.
size_t는 php ffi의 size_t 에 해당하며 실수로 int 또는 서명되지 않은 int 로 쓰지 마십시오.
Const Char * 와 같이 포인터 유형은 올바르게 작성해야합니다.
구조 선언은 정확히 일치해야합니다.
PHP FFI는 size_t를 지원하며 직접 사용해야합니다.
<?php
$ffi = FFI::cdef("
void process_data(const char *data, size_t len);
");
?>
이렇게하면 32/64 비트 플랫폼의 유형 불일치를 피합니다.
가능하면 필기 선언 대신 C 헤더 내용을 직접로드하면 오류가 줄어 듭니다.
<?php
$ffi = FFI::cdef(file_get_contents("your_lib.h"), "your_lib.so");
?>
Strace 또는 GDB를 사용하여 PHP 프로세스를 추적하고 충돌 지점을 찾으십시오.
C 헤더 파일 선언 및 테스트 통화를 단계별로 단순화하십시오.
다른 플랫폼 (Linux/Windows/MacOS)의 Size_T 및 기타 유형의 크기 차이에 유의하십시오.
<?php
$ffi = FFI::cdef("
void process_data(const char *data, size_t len);
");
$data = "example";
$ffi->process_data($data, strlen($data));
?>
이것은 유형 불일치로 인한 충돌을 방지합니다.
요약 : PHP FFI는 강력하지만 C 유형 선언이 완전히 일관되도록해야합니다. 특히 정수와 포인터 유형 사이의 대응이 필요합니다. 충돌이 발생하면 유형 불일치로 인한 런타임 오류를 피하기 위해 FFI :: CDEF () 에서 유형 정의를 확인하는 데 우선 순위가 부여됩니다.