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

PHP FFI如何将PHP数组转换为C指针数组?

在PHP FFI中调用get_random函数的正确姿势

要解决段错误问题,核心是正确将PHP字符串数组转换为C函数要求的const char *const *类型(指向常量字符串指针的常量指针)。直接传递PHP数组会导致FFI无法识别类型,传递错误内存地址引发SIGSEGV。以下是分步实现方案:

1. 加载FFI定义与动态库

首先定义函数签名并加载目标动态库:

$ffi = FFI::cdef("
    typedef unsigned long uintptr_t;
    const char *get_random(const char *const *words, uintptr_t len);
", "./librandom.so"); // 替换为你的动态库路径(Windows用.dll,macOS用.dylib)

2. 转换PHP字符串为C风格字符串

PHP字符串内部不含C要求的\0结束符,需要逐个转换为C内存中的字符串:

$phpWords = ["apple", "banana", "cherry", "date"];
$len = count($phpWords);
$cStrings = [];

foreach ($phpWords as $word) {
    // 分配足够内存:字符串长度+1(存储结束符)
    $cStr = FFI::new("char[" . (strlen($word) + 1) . "]");
    // 拷贝PHP字符串内容到C内存
    FFI::memcpy($cStr, $word, strlen($word));
    // 添加C字符串结束符
    $cStr[strlen($word)] = "\0";
    $cStrings[] = $cStr;
}

3. 构建C指针数组

创建对应const char*[]类型的数组,将每个C字符串的指针存入其中:

$cWordArray = FFI::new("const char*[$len]");
for ($i = 0; $i < $len; $i++) {
    $cWordArray[$i] = $cStrings[$i];
}

4. 调用函数并处理结果

传递构建好的指针数组和长度,将返回的C字符串转换为PHP字符串:

$result = $ffi->get_random($cWordArray, $len);
$phpResult = FFI::string($result);
echo "随机选中的单词:{$phpResult}\n";

关键注意事项

  • 内存管理:如果get_random返回的是传入数组中的字符串指针,无需手动释放$result;若返回的是函数内部分配的新字符串,需调用对应释放函数(若提供)避免内存泄漏。我们创建的$cStrings和$cWordArray会在PHP脚本结束时自动释放,也可手动调用FFI::free()提前释放。
  • 类型兼容:uintptr_t的定义需匹配目标平台,若unsigned long不兼容,可改用FFI::typeof("uintptr_t")获取系统原生类型。
  • 编码一致性:确保PHP字符串编码与C函数预期一致(如UTF-8),避免乱码。

内容的提问来源于stack exchange,提问作者Slava.In

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 14:37:44