PHP 8.1 FFI调用so库报Failed resolving C function 'getint'
PHP FFI 无法解析自定义so库函数的修复方案
核心错误原因
- 你传给
FFI::cdef()方法的头文件内容中包含了FFI_SCOPE、FFI_LIB两个PHP FFI预加载专属宏,这两个宏不属于标准C语法,会干扰cdef()对C函数声明的解析,最终导致函数符号查找失败。 - 这两个宏仅在php.ini配置FFI预加载的场景下生效,和
FFI::cdef()手动加载的模式互斥,不能混着用。
修复步骤
- 清理传给cdef的C声明内容
给cdef()传的参数必须是纯标准C的函数、类型声明,不能带PHP专属的FFI宏。你可以直接写纯声明字符串,也可以过滤原有头文件里的宏内容:<?php declare(strict_types=1); // 方案1:直接传纯函数声明,最简单 $ffi = \FFI::cdef( "int getint(int val);", "/srv/www/myapp/libs/getint.so" ); // 方案2:如果要复用原有头文件,读入后过滤掉FFI专属宏 // $header = file_get_contents('/srv/www/myapp/libs/get_int.h'); // $header = preg_replace('/#define\s+FFI_(SCOPE|LIB).*$/m', '', $header); // $ffi = \FFI::cdef($header, "/srv/www/myapp/libs/getint.so"); var_dump($ffi->getint(123)); - 验证so库的符号导出(可选排查项)
你之前用的编译命令gcc -shared -o getint.so -fPIC get_int.c是正确的,正常编译出的库会导出getint符号,可以用以下命令验证:
正常输出会包含类似nm -D /srv/www/myapp/libs/getint.so | grep getint0000000000001106 T getint的字样,其中T代表符号已导出。如果没有对应输出,再检查编译时是否加了符号隐藏参数。 - 权限检查(可选排查项)
确认PHP运行进程的用户对getint.so文件有读、执行权限,权限不足会导致库加载失败。
补充说明
如果你确实想用预加载模式调用so函数,不需要手动调用FFI::cdef(),按以下步骤配置即可:
- 保留头文件里的
FFI_SCOPE、FFI_LIB宏定义 - 在php.ini中添加配置:
ffi.preload=/srv/www/myapp/libs/get_int.h - 重启PHP进程,调用时直接用
$ffi = FFI::scope("GETINT");获取实例即可。
内容的提问来源于stack exchange,提问作者rafineria888wp
相关产品推荐
相关产品推荐

