PHP Conference Japan 2024

FFI::load

(PHP 7 >= 7.4.0, PHP 8)

FFI::load從 C 標頭檔載入 C 宣告

說明

public static FFI::load(字串 $filename): ?FFI

從 C 標頭檔載入 C 宣告。可以透過在載入的 C 標頭檔中使用特殊的 FFI_LIB 定義來指定應該載入的共享函式庫。

參數

filename

C 標頭檔的名稱。

不支援 C 預處理器指令,例如 #include#define 和 CPP 巨集無法使用,除了以下列出的特殊情況。

標頭檔應該包含一個針對 FFI_SCOPE 變數的 #define 陳述式,例如:#define FFI_SCOPE "MYLIB"。詳情請參閱類別介紹

標頭檔可以包含一個針對 FFI_LIB 變數的 #define 陳述式,以指定它所公開的函式庫。如果是系統函式庫,則只需檔案名稱,例如:#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 物件

新增註釋

使用者貢獻的註釋 2 則註釋

jungmann0 at gmail dot com
4 年前
由於除了 FFI_LIB 和 FFI_SCOPE 之外的 #include 和 #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
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