>  기사  >  백엔드 개발  >  PHP의 FFI를 사용하여 cjieba를 호출합니다.

PHP의 FFI를 사용하여 cjieba를 호출합니다.

藏色散人
藏色散人앞으로
2020-11-19 15:21:404134검색

추천: "PHP 비디오 튜토리얼"

phpjieba_ffi

PHP 7.4의 FFI를 사용하여 cjieba 단어 분할을 직접 호출하는 동적 라이브러리를 테스트하세요

CJieba를 선택하는 이유는 FFI가 C 호출을 사용하기 때문입니다. Cpp를 사용하는 경우 직접 패키지한 다음 C를 extern하여 컴파일러가 표준 C 동적 라이브러리를 생성하도록 해야 합니다.

문제 발생

세그먼트 오류

C 변수가 초기화되지 않았습니다

C 함수가 직접 호출되고 초기화 후 C 객체는 FFI를 통해 호출되지 않습니다

Null이 아닌 판단에는 FFI 사용이 필요합니다. ::isNull ($x)

포인터 형식의 배열은 foreach

포인터 형식 배열의 루프와 함께 사용할 수 없습니다

C 코드를 보면 Cut 부분이 다음과 같은 것을 발견했습니다.

CJiebaWord* Cut(Jieba handle, const char* sentence, size_t len) {
  cppjieba::Jieba* x = (cppjieba::Jieba*)handle;
  vector<string> words;
  string s(sentence, len);
  x->Cut(s, words);
  
  CJiebaWord* res = (CJiebaWord*)malloc(sizeof(CJiebaWord) * (words.size() + 1));
  size_t offset = 0;
  for (size_t i = 0; i < words.size(); i++) {
    res[i].word = sentence + offset;
    res[i].len = words[i].size();
    offset += res[i].len;
  }
  if (offset != len) {
    free(res);
    return NULL;
  }
  res[words.size()].word = NULL;
  res[words.size()].len = 0;
  return res;
}

returns a 구조체 포인터 C 언어에서 배열 이름은 실제로 배열의 첫 번째 변수의 포인터 주소이므로 포인터 주소 ++의 연산을 통해 탐색할 수 있습니다.

이 배열의 경우 처음에는 foreach 루프를 사용하고 분할 오류를 직접 보고했습니다. 나중에 C와 마찬가지로 포인터++를 직접 사용하여 C에서도 직접 작동할 수 있다는 점을 확인했습니다. 바늘.

단어 분할 결과 획득

위 코드에서 보듯이 단일 단어 분할 CJiebaWord의 경우 저장된 단어 분할이 아닌 문장+오프셋이므로 첫 번째 단어 분할 결과가 원본이어야 함 끈.

C 데모에서는 printf 형식(.은 필드 너비 및 정렬을 나타냄)이지만 PHP에는 비슷한 방법이 없습니다. substr($x->word, 0, $x-> 문자열을 가로채야 합니다. ;len)

  for (x = words; x->word; x++) {
    printf("%*.*s\n", x->len, x->len, x->word);
  }

사용예

컴파일 동적 라이브러리

make libjieba.so

Run

time php demo.php

Run c 데모

make demo
time ./demo

Result

PHP
load: 0.00025701522827148
real    1m59.619s
user    1m56.093s
sys     0m3.517s
C
real    1m54.738s
user    1m50.382s
sys     0m4.323s
CPU 占用 基本都是 12%

FFI를 사용하면 PHP의 속도는 기본적으로 다음과 같습니다. C. CPU 사용량이 많은 경우 비즈니스의 경우 다른 언어(C/C++, golang, Rust 등)를 사용하여 표준 C 동적 라이브러리를 작성하고 내보낼 수 있습니다.

FFI 사용

시스템 호출이나 SDK 호출이 필요한 FFI가 있기 전에는 PHP에서 확장 기능을 개발해야 했습니다. 그러나 확장 기능을 개발하려면 C 언어뿐만 아니라 PHP 커널에 대한 이해도 필요합니다. 어려운. 이제 훨씬 더 편리해졌습니다. FFI를 사용하여 동적 라이브러리를 직접 호출할 수 있습니다.

확장된 매크로 확장

예를 들어 Hikvision의 SDK gcc -E -P HCNetSDK.h -o HCNetSDK_unfold.h에는 유형 정의를 지원하는 매크로가 많이 있습니다. 안심하고 사용하세요

원본 주소: https://github.com /dwdcth/phpjieba_ffi

위 내용은 PHP의 FFI를 사용하여 cjieba를 호출합니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 github.io에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제