推奨: 「PHP ビデオ チュートリアル 」
phpjieba_ffi
PHP 7.4 の FFI テストを使用して、直接call cjieba Word セグメンテーション ダイナミック ライブラリ
CJieba を選択した理由は、FFI が C 呼び出し規約を使用しているためです。Cpp を使用する場合は、それを自分でパッケージ化し、コンパイラに標準 C を生成させるために C を extern する必要があります。ダイナミックライブラリ。
発生した問題
セグメンテーション違反
C 変数が初期化されていません
C が直接呼び出されますFFI
によって初期化された C オブジェクトによって関数が呼び出されない
ポインタ形式での配列のループ
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; }
単語分割結果の取得
上記のコードに示すように、単一の単語分割 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
time php demo.php
make demo time ./demo
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 の使用
システム コールまたは 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 中国語 Web サイトの他の関連記事を参照してください。