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
相关产品推荐
相关产品推荐

