将带有内部空字符的python2.7字符串传递给c ++

时间:2018-03-13 03:01:19

标签: python c++ swig python-2.x cpython

有没有办法将中间带有空字符的python2.7字符串(例如foo\0bar)传递给swig绑定中的c ++代码?

python C bindings提供了两个函数:PyString_AsStringPyString_AsStringAndSize,但这两个函数都返回空终止字符串。

1 个答案:

答案 0 :(得分:1)

正如PyString_AsStringAndSize的文档所说,除非您为NULL传递length,否则它会保留内部空字符。您显然不会这样做(因为如果您不知道长度,则无法对带有内部空字符的字符串执行任何操作)。

无论你是否想要一个终结器,它确实确保了一个空终止符,但如果这是不可接受的,那么很容易处理:只需减去它返回的长度。

所以,除非你担心Python复制缓冲区的潜在性能成本只是添加一个你不需要的空终结符(在这种情况下我不会担心 - 大多数创建字符串的方法,你'已经在缓冲区中有了终结符),这里应该没有任何问题。

证明:

#!/usr/bin/env python2.7

from ctypes import *

PyString_AsStringAndSize = pythonapi.PyString_AsStringAndSize
PyString_AsStringAndSize.argtypes = [
    py_object, POINTER(POINTER(c_int8)), POINTER(c_ssize_t)]
PyString_AsStringAndSize.restype = c_int

s = 'foo\0bar'
buf = POINTER(c_int8)()
size = c_ssize_t()

res = PyString_AsStringAndSize(s, byref(buf), byref(size))
print res
print size.value
bufa = cast(buf, POINTER(c_int8 * size.value))
print bufa.contents[:size.value]
print repr(''.join(chr(c) for c in bufa.contents[:size.value]))

输出结果为:

0
7
[102, 111, 111, 0, 98, 97, 114]
'foo\x00bar'

你想要什么,对吗?

(在C ++中,你不必做所有烦人的工作来解决ctypes我做过的事情,首先使用int8而不是char来防止它出现太聪明并且创建一个字符串,然后将其转换为数组,因为不允许使用指针算法。)

相关问题