PHP 8.5.0 Released!

FFI::load

(PHP 7 >= 7.4.0, PHP 8)

FFI::loadC のヘッダーファイルから C の宣言を読み込む

説明

public static FFI::load(string $filename): ?FFI

C のヘッダーファイルから C の宣言を読み込みます。 読み込まれる C のヘッダーファイル内で特殊な define FFI_LIB を使うことで、 読み込む共有ライブラリを指定することが可能です。

パラメータ

filename

C のヘッダーファイル名。

C のプリプロセッサーディレクティブはサポートされていません。 例えば、#include#define、プリプロセッサーマクロは動作しません。 ただし、次に挙げる特殊な場合を除きます。

このヘッダーファイルでは、#define 文で FFI_SCOPE 変数を定義すべきです (例: #define FFI_SCOPE "MYLIB")。 詳しくは FFI クラスの概要 を参照してください。

このヘッダーファイルでは、#define 文で FFI_LIB 変数を定義することで、公開するライブラリを指定しても構いません。 それがシステムライブラリなら、必要なのはファイル名だけです (例: #define FFI_LIB "libc.so.6")。カスタムライブラリなら、相対パスが必要です (例: #define FFI_LIB "./mylib.so")。

戻り値

新しく作成された FFI オブジェクトを返します。 失敗時には null を返します。

変更履歴

バージョン 説明
8.3.0 現在のシステムユーザが opcache.preload_user 設定ディレクティブで定義されたユーザと同じである場合、 事前ロードスクリプト の中で FFI::load() を呼べるようになりました。

参考

  • FFI::scope() - 事前ロード中にパースされた C の宣言を使って FFI オブジェクトをインスタンス化する

add a note

User Contributed Notes 2 notes

up
10
jungmann0 at gmail dot com
5 years ago
Since #include's and #define's other than FFI_LIB and FFI_SCOPE are not supported in the header, you may want to use the C preprocessor to pre-process your headers in order to resolve all #include's and macros.

I use -D"__attribute__(ARGS)=" to remove function attributes as well, which are not supported by FFI either.

This is my script:

echo '#define FFI_SCOPE "YOUR_SCOPE"' > header-ffi.h
echo '#define FFI_LIB "/path/to/your_lib.so"' >> header-ffi.h
cpp -P -C -D"__attribute__(ARGS)=" header_original >> header-ffi.h
up
2
ojrask at gmail dot com
5 years ago
Regarding the `FFI_LIB` constant:

The path given can be either relative, or absolute, or then refer to a library that is in your global libraries path (i.e. where libc.so.6 and friends are).

The absolute path and global lib path work as expected. The relative path does not work from the header file path, but the current working directory instead. So when you create header files for FFI usage, remember that the PHP script can be called anywhere and this means any relative paths in `FFI_LIB` will most probably fail.

Not sure if there is some possibility to make it use paths relative to the script being called, or relative to the header file being loaded. That would make more sense to me at least.

Right now `FFI_LIB` is quite unusable when it comes to making FFI-powered PHP packages that can be installed literally anywhere on a system. `FFI::cdef` works just as well, but `FFI::scope` also seems to rely on `FFI_LIB` meaning it will fail with relative paths as well.

I guess this comes from the C function `dlopen` as is.
To Top