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

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

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

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

最佳答案

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

无论您是否需要,它确实确保在末尾有一个空终止符,但如果这是 Not Acceptable ,那么处理起来很容易:只需将它返回的长度减一。

因此,除非您担心 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 以防止它过于聪明并制作一个字符串,然后将其转换为一个数组,因为不允许使用指针算法。)

关于python - 将带有内部空字符的 python2.7 字符串传递给 C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49247628/

相关文章:

c++ - llvm 可以发出跳转到函数内给定地址的代码吗?

c++ - 我无法使用 Code::Blocks 编译任何东西

c - SSL_CTX_new :unable to load ssl2 md5 routines

python - 如何使用 SWIG 接口(interface)访问 python 中的 C++ typedef 结构

python - 如何使用 python 正则表达式删除忽略 www.并且只提供域名?

python - 交替排序字符串列表

c# - 使用Direct2d Effects时出现 "error LNK2001: unresolved external symbol _CLSID_D2D1Blend"如何解决?

python - 通过 SWIG 和 Python 从第三方 .dll 共享库访问函数

python - 在 Google App Engine 开发服务器中结合 --backends 和事务任务队列有问题吗?

python - 如果是分号,则匹配除最后一个字符之外的所有字符