在 bytearray 的末尾是否需要一个明确的 NUL 字节,以便 cython 能够将其转换为以 null 结尾的 C 字符串
Is an explicit NUL-byte necessary at the end of a bytearray for cython to be able to convert it to a null-terminated C-string
将 bytearray
对象(或 bytes
对象)转换为 C 字符串时,cython-documentation 建议使用以下内容:
cdef char * cstr = py_bytearray
没有开销,因为 cstr
指向 bytearray
对象的缓冲区。
但是,C 字符串是 null-terminated,因此为了能够将 cstr
传递给 C 函数,它也必须以 null 结尾。 cython 文档不提供任何信息,无论生成的 C 字符串是否以 null 结尾。
可以向 byarray
对象显式添加 NUL
字节,例如通过使用 b'text\x00'
而不仅仅是 `b'text'。但这很麻烦,容易忘记,至少有实验证据表明不需要明确的 NUL 字节:
%%cython
from libc.stdio cimport printf
def printit(py_bytearray):
cdef char *ptr = py_bytearray
printf("%s\n", ptr)
现在
printit(bytearray(b'text'))
将所需的 "text" 打印到标准输出(在 IPython-notebook 的情况下,显然不是浏览器中显示的输出)。
但这是一个幸运的巧合还是可以保证字节数组对象(或字节对象)的缓冲区是空终止的?
我认为它是安全的(至少在 Python 3),但我会有点谨慎。
Cython 使用了 C-API 函数 PyByteArray_AsString
。 Python3 documentation for it says "The returned array always has an extra null byte appended." The Python2 version 没有那个字条,所以很难确定它是否安全。
实际上,我认为 Python 通过总是将字节数组过度分配一个并以 NULL 终止它们来解决这个问题(请参阅 source code 以了解完成此操作的示例)。
唯一要谨慎的原因是字节数组(和 Python 字符串)在字符串中包含一个 0 字节是完全可以接受的,所以它不是一个很好的指标尽头在哪里。因此,无论如何你真的应该使用他们的len
。 (虽然这是一个薄弱的论点,特别是因为你可能是初始化它们的人,所以你知道这是否应该是真的)
(我这个答案的初始版本有一些关于 _PyByteArray_empty_string
的内容。@ead 在评论中指出我对此有误,因此被删掉了...)
将 bytearray
对象(或 bytes
对象)转换为 C 字符串时,cython-documentation 建议使用以下内容:
cdef char * cstr = py_bytearray
没有开销,因为 cstr
指向 bytearray
对象的缓冲区。
但是,C 字符串是 null-terminated,因此为了能够将 cstr
传递给 C 函数,它也必须以 null 结尾。 cython 文档不提供任何信息,无论生成的 C 字符串是否以 null 结尾。
可以向 byarray
对象显式添加 NUL
字节,例如通过使用 b'text\x00'
而不仅仅是 `b'text'。但这很麻烦,容易忘记,至少有实验证据表明不需要明确的 NUL 字节:
%%cython
from libc.stdio cimport printf
def printit(py_bytearray):
cdef char *ptr = py_bytearray
printf("%s\n", ptr)
现在
printit(bytearray(b'text'))
将所需的 "text" 打印到标准输出(在 IPython-notebook 的情况下,显然不是浏览器中显示的输出)。
但这是一个幸运的巧合还是可以保证字节数组对象(或字节对象)的缓冲区是空终止的?
我认为它是安全的(至少在 Python 3),但我会有点谨慎。
Cython 使用了 C-API 函数 PyByteArray_AsString
。 Python3 documentation for it says "The returned array always has an extra null byte appended." The Python2 version 没有那个字条,所以很难确定它是否安全。
实际上,我认为 Python 通过总是将字节数组过度分配一个并以 NULL 终止它们来解决这个问题(请参阅 source code 以了解完成此操作的示例)。
唯一要谨慎的原因是字节数组(和 Python 字符串)在字符串中包含一个 0 字节是完全可以接受的,所以它不是一个很好的指标尽头在哪里。因此,无论如何你真的应该使用他们的len
。 (虽然这是一个薄弱的论点,特别是因为你可能是初始化它们的人,所以你知道这是否应该是真的)
(我这个答案的初始版本有一些关于 _PyByteArray_empty_string
的内容。@ead 在评论中指出我对此有误,因此被删掉了...)