当前位置: 首页 > 工具软件 > PHP-FFI > 使用案例 >

PHP通过FFI调用C语言动态库

越俊驰
2023-12-01

设置

  • PHP版本大于7.4
  • 开启FFI扩展ext/ffi
  • PHP-FFI要求libffi-3

使用未提供头文件的库

  1. 编辑C语言测试库源码
//File: libtest.c
int fnadd(int a,int b){
        return a+b;
}

int fnsub(int a,int b){
        return a-b;
}

编译库

$ gcc -shared -fPIC libtest.c -o libtest.so
  1. PHP语言调用库函数
<?php
//File:index.php
$lib_path = '<PATH>/libtest.so';//将<PATH>替换为库的实际路径
$lib = \FFI::cdef(<<<EOF  //类似于包含C语言head文件
			int fnadd(int a,int b);
			int fnsub(int a,int b);
			EOF, $lib_path);
//调用C库函数
echo "结果:" , $lib->fnadd(5, 6),"\n"; 
echo "结果:" , $lib->fnsub(6, 5),"\n";

使用提供了头文件的库

Cmark是一个能将Markdown文本转换为HTML文本的工具并且还提供了libcmark.so库供调用。编译安装好Cmark后,PHP就可以直接调用libcmark.so中的函数了。

  1. 先用c语言预处理将库的原头文件整成一个新的cmark-ffi.h的头文件
echo '#define FFI_SCOPE "CMARK"' > cmark-ffi.h
echo "#define FFI_LIB \/usr/local/lib/libcmark.so\"" >> cmark-ffi.h
cpp -P -C -D"__attribute__(ARGS)="/usr/local/include/cmark.h >> cmark-ffi.h
  1. PHP语言调用库函数
<?php
// 1. 加载定义的头文件
FFI::load(__DIR__ .'/cmark-ffi.h'); 

function parse_string(string $input, int $options = 0): string { 
		$ffi = FFI::scope("CMARK");//2.选择定义的域
		//3. 便可直接调用`libcmark.so`库里的函数了
        $mem_allocator = $ffi->cmark_get_default_mem_allocator();
        $parser = $ffi->cmark_parser_new_with_mem($options, $mem_allocator);
        $ffi->cmark_parser_feed($parser, $input, strlen($input));
        $document = $ffi->cmark_parser_finish($parser);
        $result = $ffi->cmark_render_html($document, $options);
        $result_php = FFI::string($result);
        $ffi->cmark_parser_free($parser);
        $ffi->cmark_node_free($document);
        return $result_php;
    }
$result = parse_string('# Title');
echo $result,"\n";

php代码执行结果:

$ php x.php
<h1>Title</h1>
 类似资料: