Heim >Backend-Entwicklung >PHP-Problem >Erlauben Sie PHP, C-Funktionen aufzurufen: FFI-Erweiterung (mit Code)

Erlauben Sie PHP, C-Funktionen aufzurufen: FFI-Erweiterung (mit Code)

醉折花枝作酒筹
醉折花枝作酒筹nach vorne
2021-06-09 17:09:442097Durchsuche

In diesem Artikel werden Ihnen die Funktionen vorgestellt, die es PHP ermöglichen, die C:FFI-Erweiterung aufzurufen. Es hat einen gewissen Referenzwert. Freunde in Not können sich darauf beziehen. Ich hoffe, es wird für alle hilfreich sein.

Erlauben Sie PHP, C-Funktionen aufzurufen: FFI-Erweiterung (mit Code)

In großen Unternehmen gibt es meist viele Programmiersprachen. Lassen Sie beispielsweise Java als Microservice-Schicht, C++ für zugrunde liegende Operationen, PHP als mittlere Schicht und schließlich JS zur Darstellung des Effekts verwenden. Der Großteil der Zusammenarbeit zwischen diesen Sprachen erfolgt über RPC, oder die Daten werden direkt in der Datenbank gespeichert und dann in verschiedenen Sprachen abgerufen. Kann unser PHP-Code diese Sprachen also direkt aufrufen? Tatsächlich hat PHP eine Erweiterungsbibliothek für uns vorbereitet, die die C-Sprache direkt aufrufen kann. Diese Erweiterungsbibliothek ist standardmäßig in PHP integriert. Es handelt sich um die FFI-Erweiterung.

Was ist FFI?

FFI, Foreign Function Interface, externe Funktionsschnittstelle. Mit dieser Erweiterung können wir einige öffentliche Bibliotheken (.dll, .so) laden, was tatsächlich bedeutet, dass wir einige C-Datenstrukturen und -Funktionen aufrufen können. Es handelt sich bereits um eine Erweiterung, die mit dem PHP-Quellcode veröffentlicht wurde. Sie können beim Kompilieren --with-ffi hinzufügen, um sie direkt in das PHP-Programm zu kompilieren.

Wir haben PHP hier bereits kompiliert, daher finden wir diese Erweiterung direkt und führen einfache Installationsschritte für die Erweiterung durch, um die Installation abzuschließen.

cd php-7.4.4/ext/ffi/
phpize
./configure
make && make install

Denken Sie nach Abschluss der Installation daran, die Erweiterung in der Datei php.ini zu öffnen. Bei dieser Erweiterung ist zu beachten, dass sie über ein Konfigurationselement ffi.enable verfügt. Standardmäßig ist der Wert dieses Konfigurationselements „preload“, wodurch nur FFI-Funktionen in der CLI-SAPI-Umgebung aktiviert werden. Natürlich können wir es auch in „true“ oder „false“ ändern, um es ein- und auszuschalten. Durch die Einstellung „true“ wird diese Erweiterung in allen Umgebungen aktiviert.

Verwenden Sie FFI, um C-Funktionen aufzurufen

Als nächstes werfen wir einen kurzen Blick darauf, wie es C-Funktionen aufruft.

// 创建一个 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

Wir haben zwei Objekte erstellt und die Funktionen printf() und pow() von C aufgerufen. FFI::cdef() wird zum Erstellen eines FFI-Objekts verwendet. Es empfängt zwei Parameter, einer ist eine Zeichenfolge, die die Deklarationssequenz der regulären C-Sprache enthält (Typ, Struktur, Funktion, Variable usw.).

Tatsächlich kann diese Zeichenfolge aus der C-Header-Datei kopiert und eingefügt werden. Der andere Parameter ist der Name der gemeinsam genutzten Bibliotheksdatei, die geladen und verknüpft werden soll. Das ist die .dll- oder .so-Datei, die wir benötigen, die der von uns deklarierten Zeichenfolge entspricht. In libc.so.6 gibt es beispielsweise keine Berechnungsfunktion wie pow(), daher müssen wir das mathematisch bezogene C finden Bibliothek für Sprachberechnungsfunktionen.

Variablen und Arrays definieren

Natürlich kann FFI auch Variablen und Arrays definieren.

// 创建一个 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),内存大小

Verwenden Sie die Funktion FFI::new(), um eine C-Datenstruktur, also eine Variablendeklaration, zu erstellen, und der Inhalt dieser Variablen wird im cdata-Attribut gespeichert. Das Array kann direkt mit dem Rückgabewert dieser Funktion arbeiten. Wenn wir die Verwendung beenden möchten, müssen wir natürlich immer noch FFI::free() verwenden, um die Variablen freizugeben, genau wie bei der C-Sprachentwicklung.

Zusammenfassung

Fühlt es sich nicht sehr edel an? Bitte beachten Sie jedoch, dass die von FFI aufgerufenen C-Funktionen nicht so effizient sind wie die von PHP selbst aufgerufenen. Mit dieser pow()-Funktion ist es beispielsweise effizienter, PHP selbst zu verwenden. Obwohl die FFI-Erweiterung gleichzeitig mit PHP veröffentlicht wurde, ist sie darüber hinaus noch experimentell. Mit anderen Worten: Diese Erweiterung ist für andere Funktionen vorbereitet, die möglicherweise in Zukunft verwendet werden, und es bestehen noch viele Unsicherheiten. Wenn Sie also ähnliche Funktionen in einer Produktionsumgebung benötigen, müssen Sie noch eingehendere Recherchen durchführen.

Testcode:

https://github.com/zhangyue0503/dev-blog/blob/master/php/202004/source/%E8%AE%A9PHP%E8%83%BD%E5%A4%9F%E8%B0%83%E7%94%A8C%E7%9A%84%E5%87%BD%E6%95%B0-FFI%E6%89%A9%E5%B1%95.php

Empfohlenes Lernen: php-Video-Tutorial

Das obige ist der detaillierte Inhalt vonErlauben Sie PHP, C-Funktionen aufzurufen: FFI-Erweiterung (mit Code). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:segmentfault.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen