open_memstream返回的指针表示为b''在Cython中

时间:2018-05-08 10:02:15

标签: cython

我在cdef对象中有以下cython代码:

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("pointer", bp, "size_t:", size)中打印的指针和print("bt", bt)中打印的字节串让我担心出现问题。指针只是('pointer', b'', 'size_t:', 6144),而bytestring似乎包含来自Python源代码的文本:

  

x00 \ x00规范化编码名称。\ n \ n规范化的作用如下   如下:除了使用的点之外的所有非字母数字\ n字符   对于Python包名称是\ n折叠并替换为   单个下划线,例如\' - ;#\' \ n变为\' _ \'。领导和   删除尾随下划线。\ n \ n请注意编码名称   应该只是ASCII;如果他们确实使用\ n非ASCII字符,   这些必须是Latin-1兼容的。\ n \ n \ x00 \ x00 \

(它主要只是字节符号)。

我确定write_padded_binary_works,因为当我给它一个常规文件描述符时它会起作用。我也确定open_memstream有效,因为当我使用cn.fprintf(stream, "hello");而不是write_padded_binary进行尝试时,输出为('bt', b'hello')。但是,指针也是('pointer', b'hello', 'size_t:', 5)所以我必须误解一些与指针相关的东西我认为......

1 个答案:

答案 0 :(得分:1)

您遇到的问题(被诊断为elsewhere)是您无法将char*直接传递给Python函数。当您做Cython尝试将其转换为字符串时(这没有意义,因为它只是保存二进制数据,因此将其解释为空终止的C字符串会导致它读取任意长度,直到找到0。

这种情况与printctypes.string_at都有问题。两种情况下的技巧是首先将其转换为适当大小的整数。保证C uintptr_t足够大以容纳整数,因此是合适的选择:

from libc.stdint cimport uintptr_t

print("pointer", <uintptr_t>bp, "size_t:", size)
bt = c.string_at(<uintptr_t>bp, size)