PHPのFFIを使用してcjiebaを呼び出す

藏色散人
リリース: 2023-04-09 16:36:02
転載
3998 人が閲覧しました

推奨: 「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 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;
}
ログイン後にコピー

返されるのは構造体です。ポインタ。C 言語では、配列名は実際には配列内の最初の変数のポインタ アドレスなので、ポインタ アドレスの操作を通じて調べることができます。FFI ではどうですか?

この配列では、最初は foreach ループを使用し、セグメンテーション エラーを直接報告しました。その後、C のようなポインターを直接使用して、それが実行可能であることがわかりました。FFI に高く評価します。 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
ログイン後にコピー
実行
time php demo.php
ログイン後にコピー

C デモを実行します

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 を使用すると、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 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
php
ソース:github.io
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!