python — передача строки python2.7 с внутренними нулевыми символами в переполнение стека

Есть ли способ передать строку python2.7 с нулевым символом в середине (например, foo\0bar) код C ++ в привязках Swig?

привязки Python C обеспечить две функции: PyString_AsString а также PyString_AsStringAndSize, но обе функции возвращают строки с нулевым символом в конце.

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 чтобы он не был слишком умным и не создавал строку, а затем приводил ее к массиву, потому что арифметика указателей не допускается.)

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]