FFI::load

(PHP 7 >= 7.4.0, PHP 8)

FFI::loadLoads C declarations from a C header file

说明

public static FFI::load ( string $filename ) : FFI|null

Loads C declarations from a C header file. It is possible to specify shared libraries that should be loaded, using special FFI_LIB defines in the loaded C header file.

参数

filename

The name of a C header file.

C preprocessor directives are not supported, i.e. #include, #define and CPP macros do not work, except for special cases listed below.

The header file should contain a #define statement for the FFI_SCOPE variable, e.g.: #define FFI_SCOPE "MYLIB". Refer to the class introduction for details.

The header file may contain a #define statement for the FFI_LIB variable to specify the library it exposes. If it is a system library only the file name is required, e.g.: #define FFI_LIB "libc.so.6". If it is a custom library, a relative path is required, e.g.: #define FFI_LIB "./mylib.so".

返回值

Returns the freshly created FFI object, or null on failure.

参见

  • FFI::scope() - Instantiates an FFI object with C declarations parsed during preloading

User Contributed Notes

jungmann0 at gmail dot com 20-Jun-2020 07:20
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
ojrask at gmail dot com 03-Feb-2020 07:23
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.