在Cython中由open_memstream返回的指针表示为b'' [英] Pointer returned by open_memstream represented as b'' in Cython

查看:75
本文介绍了在Cython中由open_memstream返回的指针表示为b''的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在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 输出为('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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆