当前位置: 首页> 最新文章列表> FFI::memcpy 在 PHP 中复制 C 语言结构体数组的实现

FFI::memcpy 在 PHP 中复制 C 语言结构体数组的实现

gitbox 2025-06-06

一、环境准备

确保你的 PHP 安装启用了 FFI 扩展。可以通过修改 php.ini 文件,添加如下配置:

ffi.enable=1

接着,我们需要一个 C 语言结构体定义,例如:

typedef struct {
    int id;
    float value;
} Item;

我们将在 PHP 中通过 C 的声明来定义这个结构体,并操作一个结构体数组。


二、在 PHP 中使用 FFI 声明结构体

$ffi = FFI::cdef("
    typedef struct {
        int id;
        float value;
    } Item;

    void *memcpy(void *dest, const void *src, size_t n);
", "libc.so.6"); // Linux 下 libc 的路径,Windows 下可能需要改为 "msvcrt.dll"

三、创建结构体数组并初始化

我们创建一个结构体数组,初始化若干个元素。

$length = 3;
$items1 = $ffi->new("Item[$length]");

$items1[0]->id = 1;
$items1[0]->value = 3.14;

$items1[1]->id = 2;
$items1[1]->value = 2.71;

$items1[2]->id = 3;
$items1[2]->value = 1.62;

四、使用 FFI::memcpy 实现结构体数组的复制

我们需要先为目标数组分配内存,再用 memcpy 进行内存复制。

$items2 = $ffi->new("Item[$length]");

// 计算总字节数:每个结构体的大小乘以数量
$size = FFI::sizeof($items1);

// 使用 memcpy 复制内存
$ffi->memcpy(FFI::addr($items2[0]), FFI::addr($items1[0]), $size);

五、验证复制结果

for ($i = 0; $i < $length; $i++) {
    echo "Item {$i}:\n";
    echo "  ID: " . $items2[$i]->id . "\n";
    echo "  Value: " . $items2[$i]->value . "\n";
}

输出应如下:

Item 0:
  ID: 1
  Value: 3.14
Item 1:
  ID: 2
  Value: 2.71
Item 2:
  ID: 3
  Value: 1.62

六、注意事项

  1. memcpy 是按字节复制,确保目标内存区域已经分配好足够的空间;

  2. FFI::sizeof 可以安全地用于获取数组所占字节大小;

  3. 如果你想通过脚本调用的方式运行 PHP FFI 代码,记得在命令行中使用 php -dffi.enable=1 yourfile.php

  4. 在部分平台(如 macOS 或 Windows)上,C 标准库文件名不同,需要根据实际路径修改 cdef 中的库名。