You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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()手动加载的模式互斥,不能混着用。

修复步骤

  1. 清理传给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));
    
  2. 验证so库的符号导出(可选排查项)
    你之前用的编译命令gcc -shared -o getint.so -fPIC get_int.c是正确的,正常编译出的库会导出getint符号,可以用以下命令验证:
    nm -D /srv/www/myapp/libs/getint.so | grep getint
    
    正常输出会包含类似0000000000001106 T getint的字样,其中T代表符号已导出。如果没有对应输出,再检查编译时是否加了符号隐藏参数。
  3. 权限检查(可选排查项)
    确认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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 10:36:16