PHP Conference Japan 2024

FFI::load

(PHP 7 >= 7.4.0, PHP 8)

FFI::load从 C 头文件中加载 C 声明

描述

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

从 C 头文件中加载 C 声明。可以使用在加载的 C 头文件中使用特殊的 FFI_LIB 定义来指定要加载的共享库。

参数

filename

C 头文件的名称。

不支持 C 预处理器指令,即 #include#define 和 CPP 宏不起作用,以下列出的特殊情况除外。

头文件*应该*包含 #define 语句,用于 FFI_SCOPE 变量,例如:#define FFI_SCOPE "MYLIB"。有关详细信息,请参阅类介绍

头文件*可以*包含 #define 语句,用于 FFI_LIB 变量以指定其公开的库。如果它是系统库,则只需要文件名,例如:#define FFI_LIB "libc.so.6"。如果它是自定义库,则需要相对路径,例如:#define FFI_LIB "./mylib.so"

返回值

返回新创建的 FFI 对象,或者在失败时返回 null

变更日志

版本 描述
8.3.0 FFI::load() 现在允许在预加载脚本中使用,前提是当前系统用户与 opcache.preload_user 配置指令中定义的用户相同。

参见

  • FFI::scope() - 使用在预加载期间解析的 C 声明实例化 FFI 对象

添加注释

用户贡献的注释 2 条注释

10
jungmann0 at gmail dot com
4 年前
由于头文件中不支持 #include 和除 FFI_LIB 和 FFI_SCOPE 之外的 #define,您可能需要使用 C 预处理器预处理您的头文件以解析所有 #include 和宏。

我还使用 -D"__attribute__(ARGS)=" 来删除函数属性,FFI 也不支持这些属性。

这是我的脚本

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
2
ojrask at gmail dot com
4 年前
关于 `FFI_LIB` 常量

给定的路径可以是相对路径、绝对路径,也可以引用全局库路径中的库(即 libc.so.6 和同类库所在的位置)。

绝对路径和全局库路径按预期工作。相对路径不是从头文件路径工作,而是从当前工作目录工作。因此,当您为 FFI 使用创建头文件时,请记住 PHP 脚本可以在任何位置调用,这意味着 `FFI_LIB` 中的任何相对路径都极有可能失败。

不确定是否有可能使其使用相对于被调用的脚本的路径,或相对于正在加载的头文件的路径。至少对我来说,那样更有意义。

目前,在创建可以在系统任何位置安装的 FFI 支持的 PHP 包时,`FFI_LIB` 非常不可用。`FFI::cdef` 工作得很好,但是 `FFI::scope` 似乎也依赖于 `FFI_LIB`,这意味着它也会在使用相对路径时失败。

我想这是从 C 函数 `dlopen` 而来的。
To Top