【发布时间】:2021-03-16 06:55:35
【问题描述】:
假设我在 C++ 中有 char content[500],它包含一些未知编码的字符,我想通过 ctypes 回调将它传递给 python 3 代码。
这是我创建的演示代码:
typedef int (*callback)(char *);
extern "C" {
void foo(callback cb);
}
void foo(callback cb) {
char hello_world[] = {'h','e','l','l','o','\0','w','o','r','l','d'};
cb(hello_world);
}
Python 3 代码:
from ctypes import *
callback = CFUNCTYPE(c_int, c_char*11)
def py_callback(b):
with open('/tmp/test', 'wb') as f:
f.write(b)
return 0
cb = cdll.LoadLibrary("/tmp/callback.so")
cb.foo(callback(py_callback))
我以为我会在 /tmp/test 中看到“hello\0world”,但我看到的是以下内容:
# hexdump -C /tmp/test
00000000 50 5e 46 27 fc 7f 00 00 00 00 00 |P^F'.......|
0000000b
如果我将回调声明为callback = CFUNCTYPE(c_int, c_char_p),则它无法处理两者之间的空终止字符。
即使两者之间没有以空字符结尾的字符,我也需要调用f.write(b.decode('utf8')) 以使其工作,但这意味着我需要提前知道编码,而我不需要。因此,我只想将数组中的任何字节写入文件。
建议?
【问题讨论】:
-
有点离题,但你为什么不使用
char hello_world[] = "hello\0world";。你知道\0是一个字符串终止符,对吧?你为什么要包括<string>? -
@JHBonarius 是的,我知道
\0是一个字符串终止符。我故意在上面的示例中使用它来演示我想将完整的数组写入文件,而不是只将字符串(将只是hello)写入文件。让我放弃无用的#include,我正在玩代码,忘记删除它。 -
@JHBonarius 我查看了您的链接,我尝试将
c_char*11更改为c_ubyte*11,然后将f.write(b)更改为f.write(str(bytearray(b))),但它在/tmp/test和5 中给出了bytearray(b'\xc0c\xf6\xef\xfc\x7f\x00\x00\x00\x00\x00')\0最后似乎不对。
标签: python c++ python-3.x ctypes