首頁  >  文章  >  後端開發  >  如何在PHP中呼叫C的函數

如何在PHP中呼叫C的函數

autoload
autoload原創
2021-04-06 15:41:192594瀏覽

如何在PHP中呼叫C的函數

    FFI提供了高階語言直接的互相調用,而對於PHP來說,FFI讓我們可以方便的呼叫C語言寫的各種函式庫。其實作有大量的PHP擴充是對一些已有的C函式庫的包裝,例如常用的mysqli, curl, gettext#等,PECL 中也有大量的類似擴充。傳統的方式,當我們需要用一些已有的C語言的函式庫的能力的時候,我們需要用C語言寫wrapper,把他們包裝成擴展,這個過程就需要大家去學習PHP的擴充要怎麼寫,當然現在也有一些方便的方式,像是Zephir. 但總還是有一些學習成本的,而有了FFI以後,我們就可以直接在PHP腳本中呼叫C語言寫的函式庫中的函數了。而C語言幾十年的歷史中,累積了大量的優秀的庫,FFI#直接讓我們可以方便的享受這個龐大的資源了。

    注意:FFI應在PHP7.4版本後使用

// 创建一个 FFI 对象,加载 libc 并且导入 printf 函数
$ffi_printf = FFI::cdef(
    "int printf(const char *format, ...);", // C 的定义规则
    "libc.so.6"); // 指定 libc 库
// 调用 C 的 printf 函数
$ffi_printf->printf("Hello %s!\n", "world"); // Hello World

// 加载 math 并且导入 pow 函数
$ffi_pow = FFI::cdef(
    "double pow(double x, double y);", 
    "libboost_math_c99.so.1.66.0");
// 这里调用的是 C 的 pow 函数,不是 PHP 自己的
echo $ffi_pow->pow(2,3), PHP_EOL; // 8

    創建了兩個對象,分別呼叫了Cprintf()pow() 函數。 FFI::cdef() 是用於建立一個 FFI 對象,它接收兩個參數,一個是包含常規C語言(型別、結構、函數、變數等)宣告序列的字串。實際上,這個字串可以從C頭檔複製貼上。而另一個參數則是要載入並定義連結的共享庫檔案的名稱。也就是我們需要的.dll .so 文件,它與我們聲明字串是對應的,例如在 libc.so.6 文件中並沒有pow() 這類的運算函數,所以我們就要找出math 相關的C 語言計算函數函式庫。

定義變數和陣列

// 创建一个 int 变量
$x = FFI::new("int");
var_dump($x->cdata); // int(0)

// 为变量赋值
$x->cdata = 5;
var_dump($x->cdata); // int(5)

// 计算变量
$x->cdata += 2;
var_dump($x->cdata); // int(7)


// 结合上面的两个 FFI 对象操作

echo "pow value:", $ffi_pow->pow($x->cdata, 3), PHP_EOL;
// pow value:343
$ffi_printf->printf("Int Pow value is : %f\n", $ffi_pow->pow($x->cdata, 3));
// Int Pow value is : 343.000000


// 创建一个数组
$a = FFI::new("long[1024]");
// 为数组赋值
for ($i = 0; $i < count($a); $i++) {
    $a[$i] = $i;
}
var_dump($a[25]); // int(25)

$sum = 0;
foreach ($a as $n) {
    $sum += $n;
}
var_dump($sum); // int(523776)

var_dump(count($a)); // int(1024) 数组长度
var_dump(FFI::sizeof($a)); // int(8192),内存大小

    使用FFI::new() 函數來建立一個 C 的資料結構,也就是變數聲明,這些變數的內容將保存在cdata 屬性中。而數組則直接就可以操作這個函數的回傳值。當然,當我們要結束使用的時候,還是需要使用 FFI::free() 來釋放變數的,就和 C 語言的開發一樣。

推薦:2021年PHP面試題大匯總(收藏)》《php影片教學

以上是如何在PHP中呼叫C的函數的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn