在Cython中由open_memstream返回的指针表示为b'' [英] Pointer returned by open_memstream represented as b'' in Cython
问题描述
我在cdef对象中具有以下cython代码:
I have the following cython code in a cdef object:
def __getstate__(self):
cdef char *bp
cdef size_t size
cdef cn.FILE *stream
stream = cn.open_memstream(&bp, &size)
cn.write_padded_binary(self.im, self.n, 256, stream)
cn.fflush(stream);
cn.fclose(stream)
print("pointer", bp, "size_t:", size)
# ('pointer', b'', 'size_t:', 6144)
bt = c.string_at(bp, size)
print("bt", bt)
cn.free(bp)
return bt
但是,指针打印在 print中(指针,bp, size_t:,大小)
和在 print( bt,bt)
中打印的字节串使我担心出了点问题。指针只是('pointer',b'','size_t:',6144)
,字节串似乎包含Python源代码中的文本:
However, the pointer printed in print("pointer", bp, "size_t:", size)
and the bytestring that is printed in print("bt", bt)
makes me worried that something is wrong. The pointer is just ('pointer', b'', 'size_t:', 6144)
and the bytestring seems to contain text from Python source code:
x00\x00归一化编码名称。\n\n归一化为
,除以下所有非字母数字\n字符将
用于Python软件包名称的点折叠了并替换为
下划线,例如-’-;#\’\n变成\’_\’。注意,编码名称
应该仅是ASCII;否则,将删除开头的和
的下划线。如果它们确实使用n非ASCII字符,则
必须与Latin-1兼容。\n\n \x00\x00\
x00\x00 Normalize an encoding name.\n\n Normalization works as follows: all non-alphanumeric\n characters except the dot used for Python package names are\n collapsed and replaced with a single underscore, e.g. \' -;#\'\n becomes \'_\'. Leading and trailing underscores are removed.\n\n Note that encoding names should be ASCII only; if they do use\n non-ASCII characters, these must be Latin-1 compatible.\n\n \x00\x00\
(虽然大多只是字节符号)。
(It's mostly just byte-symbols though).
我确信 write_padded_binary_works
,因为当我给它一个常规文件描述符时它可以工作。我也确信open_memstream可以工作,因为当我尝试使用 cn.fprintf(stream, hello);
而不是 write_padded_binary $ c时, $ c>输出为
('bt',b'hello')
。但是,指针也是('pointer',b'hello','size_t:',5)
,所以我一定会误解我认为与指针相关的东西...
I am sure the write_padded_binary_works
, because it works when I give it a regular file descriptor. I am also sure open_memstream works because when I try it with cn.fprintf(stream, "hello");
instead of the write_padded_binary
the output is ('bt', b'hello')
. However, the pointer is also ('pointer', b'hello', 'size_t:', 5)
so I must be misunderstanding something pointer-related I think...
推荐答案
您遇到的问题(诊断为其他地方)是您不能将 char *
直接传递给Python函数。当您执行此操作时,Cython会尝试将其转换为字符串(这没有意义,因为它仅保存二进制数据,因此将其解释为以空终止的C字符串会导致它读取任意长度,直到找到0。
The issue you're having (diagnosed elsewhere) is that you can't pass a char*
directly to Python functions. When you do Cython attempts to convert it into a string (which doesn't make sense because it's just holding binary data, so interpreting it as a null terminated C string causes it to read an arbitrary length until it finds a 0.
这种情况会同时出现 print
和 ctypes.string_at
的问题。在这两种情况下,技巧都是先将其转换为适当大小的整数。C uintptr_t
确保足够大以容纳整数,因此适当的选择是:
This cases issues with both print
and ctypes.string_at
. The trick in both cases is to cast it to an appropriately sized integer first. The C uintptr_t
is guaranteed to be large enough to hold an integer, so is the appropriate choice:
from libc.stdint cimport uintptr_t
print("pointer", <uintptr_t>bp, "size_t:", size)
bt = c.string_at(<uintptr_t>bp, size)
这篇关于在Cython中由open_memstream返回的指针表示为b''的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!