php-ffi: Return type const char* 是一个字符串

php-ffi: Return type const char* is a string

为什么 const char * 的结果是 stringchar * 对象“字节数组”?

一个简单的例子:

$ffi = FFI::cdef(
  "const char *strerror(int errnum);",
  "libc.so.6"
);
var_dump($ffi->strerror(1));

returns

string(23) "Operation not permitted"

从定义中删除 const returns:

object(FFI\CData:char*)#1074 (1) {
  [0]=>
  string(1) "O"
}

背景

动态链接外部 C 库的函数 returns 包含 NULL 字节的二进制数据。当 const 在头文件的定义中时,结果字符串不完整 = 缩短为第一个 NULL 字节 = 损坏的文件。

我的解决方法

从定义中删除 const

$array = $ffi->strerror(1);
$string = FFI::string($array);

returns 正确的完整字符串。

(在现实生活中,FFI::string($array, $size) 的 $size 是已知的,并从 C 库的不同函数返回。)

在定义中删除 const 或添加 unsigned 似乎是合理的解决方法(参见 https://github.com/dstogov/php-ffi/issues/42#issuecomment-791237784

例子

下降const

$ffi = FFI::cdef(
  "char *strerror(int errnum);",
  "libc.so.6"
);
$array = $ffi->strerror(1);
$string = FFI::string($array);
var_dump($string);

添加 unsigned(或更改为 uint8_t

$ffi = FFI::cdef(
  "const unsigned char *strerror(int errnum);",
  "libc.so.6"
);
$byteArray = $ffi->strerror(1);
$charType = FFI::type('char*');
$castedValue = FFI::cast($charType, $byteArray);
$string = FFI::string($castedValue);
var_dump($string);