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 中混合使用 str
和 bytes
,我能看到的唯一解决方案是自定义类型映射。
我有一个像这样的 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 中混合使用 str
和 bytes
,我能看到的唯一解决方案是自定义类型映射。