【问题标题】:How to pass strings from PHP via FFI to c / tensorflow如何通过 FFI 将字符串从 PHP 传递到 c / tensorflow
【发布时间】:2021-11-07 03:25:45
【问题描述】:

关于上下文的几句话

我正在开发一个 PHP 库,它使用 PHP FFI 使 tensorflow 在 PHP 中可用。该库的一部分必须将字符串传递给 tensorflow 的 c 库。为了能够做到这一点,c头文件中有这些定义:

extern void TF_StringInit(TF_TString *t);

extern void TF_StringCopy(TF_TString *dst, unsigned const char *src,
                                         size_t size);

经过大量调试,我得到了将字符串传递到 TF_TString 的代码:

// Initialize the TF_TString
$tstr = TensorFlow::$ffi->new('TF_TString[1]');
TensorFlow::$ffi->TF_StringInit(FFI::addr($tstr[0]));

// Unpack the input string
$unpacked = unpack('C*', $str);
$input = FFI::new('uint8_t[' . count($unpacked) . ']');
foreach($unpacked as $i=>$part) {
    $input[$i - 1] = $part;
}

// Copy the unpacked string into the TF_TString
TensorFlow::$ffi->TF_StringCopy(FFI::addr($tstr[0]), $input, strlen($str) + 1);

问题

如果$strHello World,我希望TF_TString 现在包含Hello World

而是0Hello World

所以字符串总是以0为前缀。

进一步的想法

理论上,这个问题有可能发生,因为我的逻辑将字符串从 tensorflow 转换回 php。但是,tensorflow 有一个名为StringJoin 的内部操作,它需要两个字符串作为输入,然后将它们连接起来。如果我对字符串Hello World 使用该操作,我会得到4HelloR World。由于在连接词之间有一个新字符 R,我认为问题出在我的编码上,而不是其他地方。

我期待任何形式的意见

这是一个长期的问题,因为我不希望有很多人使用 PHP FFI,但也许(希望如此!)有人对 c 中的字符串有更多的了解可以提供帮助。

【问题讨论】:

  • 请移除标签 C++

标签: php c string ffi


【解决方案1】:

您的尝试过于复杂。你不需要使用任何数组,你不需要“解包” PHP 字符串。 this page上的第一个例子 表明您可以直接将 PHP 字符串传递给 const char * 参数。

这是一个应该可以工作的简单示例:

$ffi = FFI::cdef('

typedef struct TF_TString {
  char raw[24];
} TF_TString;

void TF_StringInit(TF_TString *t);
void TF_StringCopy(TF_TString *dst, const char *src, size_t size);

', 'tensorflow.dll');

// Allocate a TF_TString struct
$tstr = $ffi->new('TF_TString');

// Initialize it
$ffi->TF_StringInit(FFI::addr($tstr));

// Copy a PHP string to it
$s = 'Hello World';
$ffi->TF_StringCopy(FFI::addr($tstr), $s, strlen($s));

【讨论】:

  • 感谢您的建议。我最初尝试了一个类似的解决方案,尝试了很多事情导致我得到了更复杂的版本。我也试过你的确切代码,但它仍然显示同样的问题。一旦我再次读取字符串,它就会以随机字符为前缀,并且最后一个字符丢失(因为您正在执行 strlen($s) 而不是我正在执行的 strlen($s)+1 )。可悲的是,这无济于事:(
  • @Moritur “一旦我再次阅读字符串” 你是怎么做到的?
  • 我有不同的方法来查看结果,一种是使用 Tensorflows StringJoin op,然后执行我接下来要解释的操作。这样我可以看到提供给 StringJoin OP 的不同字符串已经包含无效字符。为了再次在 PHP 中获取字符串,我执行以下操作: $td = TensorFlow::$ffi->TF_TensorData($cData) $tstr = TensorFlow::$ffi->cast('TF_TString', $td); $size = TensorFlow::$ffi->TF_StringGetSize(FFI::addr($tstr)); $output = FFI::string($tstr, $size);
  • @Moritur 我不知道 StringJoin,但是像这样使用 FFI::string() 肯定是错误的,并且会给出不正确的结果。
猜你喜欢
  • 2021-10-31
  • 2017-06-03
  • 2020-05-20
  • 1970-01-01
  • 1970-01-01
  • 2010-10-26
  • 1970-01-01
  • 2017-04-10
  • 1970-01-01
相关资源
最近更新 更多