SWIG 'cstring.i' Python return 字节类型而不是字符串类型

SWIG 'cstring.i' Python return byte type instead of string type

我有一个像这样的 C 函数

int foo(void ** buf, int * buf_size)

而我是用cstring.i包裹起来用在Python 3.包裹后的Python函数的结果是string类型的。

有没有办法得到二进制类型的结果?

背景:buf 填充的数据是 msgpack 编码数据,因此在 Python 中使用 str.decode 不是一个选项。 Python 的 msgpack 实现只接受二进制数据。

我在 https://github.com/bit-01101/ctypesgen

的帮助下使用 ctypes 解决了我的问题

如果您使用 %cstring_output_allocate_size 包装函数 _wrap_foo 调用 SWIG_FromCharPtrAndSize(),它具有以下解码逻辑:

#if PY_VERSION_HEX >= 0x03000000
#if defined(SWIG_PYTHON_STRICT_BYTE_CHAR)
      return PyBytes_FromStringAndSize(carray, (Py_ssize_t)(size));
#else
#if PY_VERSION_HEX >= 0x03010000
      return PyUnicode_DecodeUTF8(carray, (Py_ssize_t)(size), "surrogateescape");
#else
      return PyUnicode_FromStringAndSize(carray, (Py_ssize_t)(size));
#endif
#endif
#else
  return PyString_FromStringAndSize(carray, (Py_ssize_t)(size));
#endif

因此您可以通过#defining SWIG_PYTHON_STRICT_BYTE_CHAR 获取字节而不是 unicode 字符串。 http://www.swig.org/Doc3.0/Python.html 中对此进行了记录,因此这是一项官方功能。但是因为它是一个全局开关,所以它只有在你希望所有的字符串参数都映射到字节时才有用。如果您需要在 API 中混合使用 strbytes,我能看到的唯一解决方案是自定义类型映射。