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

时间:2016-08-10 18:24:25

标签: python swig

我有一个类似

的C函数
int foo(void ** buf, int * buf_size)

我使用cstring.i来包装它以便在Python 3中使用。包装的Python函数的结果是string类型。

有没有办法将结果作为二进制类型?

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

2 个答案:

答案 0 :(得分:2)

如果您使用%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,我可以看到的唯一解决方案是自定义类型地图。

答案 1 :(得分:0)

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

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