Maison  >  Article  >  développement back-end  >  Autoriser PHP à appeler des fonctions C : extension FFI (avec code)

Autoriser PHP à appeler des fonctions C : extension FFI (avec code)

醉折花枝作酒筹
醉折花枝作酒筹avant
2021-06-09 17:09:442054parcourir

Cet article vous présentera les fonctions qui permettent à PHP d'appeler l'extension C:FFI. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer. J'espère qu'il sera utile à tout le monde.

Autoriser PHP à appeler des fonctions C : extension FFI (avec code)

Dans les grandes entreprises, il existe généralement de nombreux langages de programmation. Par exemple, laissez Java être utilisé comme couche de microservice, C++ pour les opérations sous-jacentes, PHP comme couche intermédiaire et enfin JS pour afficher l'effet. La plupart de la coopération entre ces langages s'effectue via RPC, ou les données sont directement stockées dans la base de données puis récupérées en utilisant différents langages. Alors, notre code PHP peut-il appeler directement ces langages ? En fait, PHP nous a vraiment préparé une bibliothèque d'extensions qui peut appeler directement le langage C, et cette bibliothèque d'extensions est déjà intégrée à PHP par défaut. Il s'agit de l'extension FFI.

Qu'est-ce que FFI

FFI, Foreign Function Interface, interface de fonction externe. Cette extension nous permet de charger certaines bibliothèques publiques (.dll, .so), ce qui signifie en fait que nous pouvons appeler certaines structures de données et fonctions C. C'est déjà une extension publiée avec le code source PHP. Vous pouvez ajouter --with-ffi lors de la compilation pour la compiler directement dans le programme PHP.

Nous avons déjà compilé PHP ici, nous pouvons donc trouver directement cette extension et effectuer des étapes simples d'installation de l'extension pour terminer l'installation.

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

Après l'installation, pensez à ouvrir l'extension dans le fichier php.ini. Une chose à noter à propos de cette extension est qu'elle possède un élément de configuration ffi.enable. Par défaut, la valeur de cet élément de configuration est "preload", qui active uniquement les fonctionnalités FFI dans l'environnement CLI SAPI. Bien sûr, nous pouvons également le changer en « vrai » ou « faux » pour l'activer et le désactiver. La définition sur "true" activera cette extension dans tous les environnements.

Utiliser FFI pour appeler des fonctions C

Ensuite, jetons un bref aperçu de la façon dont il appelle les fonctions C.

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

Nous avons créé deux objets et appelé respectivement les fonctions printf() et pow() du C. FFI::cdef() est utilisé pour créer un objet FFI. Il reçoit deux paramètres, l'un est une chaîne contenant la séquence de déclaration du langage C régulier (type, structure, fonction, variable, etc.).

En fait, cette chaîne peut être copiée-collée à partir du fichier d'en-tête C. L'autre paramètre est le nom du fichier de bibliothèque partagée à charger et à définir pour la liaison. C'est le fichier .dll ou .so dont nous avons besoin, qui correspond à la chaîne que nous déclarons. Par exemple, il n'y a pas de fonction de calcul telle que pow() dans libc.so.6, nous devons donc trouver le C lié aux mathématiques. Bibliothèque de fonctions de calcul du langage.

Définir des variables et des tableaux

Bien sûr, FFI peut également définir des variables et des tableaux.

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

Utilisez la fonction FFI::new() pour créer une structure de données C, c'est-à-dire une déclaration de variable, et le contenu de ces variables sera stocké dans l'attribut cdata. Le tableau peut opérer directement sur la valeur de retour de cette fonction. Bien sûr, lorsque nous voulons mettre fin à l'utilisation, nous devons toujours utiliser FFI::free() pour libérer les variables, tout comme le développement du langage C.

Résumé

Ça ne semble pas génial ? Mais attention, les fonctions C appelées par FFI ne sont pas aussi efficaces que celles appelées par PHP lui-même. Par exemple, avec cette fonction pow(), il est plus efficace d'utiliser PHP lui-même. De plus, bien que l'extension FFI ait été publiée simultanément avec PHP, elle est encore expérimentale. En d’autres termes, cette extension est préparée pour d’autres fonctions qui pourraient être utilisées dans le futur, et de nombreuses incertitudes subsistent. Par conséquent, si vous avez besoin de fonctions similaires dans un environnement de production, vous devez toujours effectuer des recherches plus approfondies.

Code de test :

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

Apprentissage recommandé : Tutoriel vidéo php

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer