用Cython创建C语言封装器 - Python

1 投票
2 回答
1595 浏览
提问于 2025-04-16 01:57

我一直在尝试弄明白如何包装以下的C语言函数:compress.ccompress.h

我试着按照教程的步骤来做,但在创建了.pxd文件后,我就不知道接下来该怎么做了 :|

根据我理解的,这应该是我应该有的pxd文件:

cdef extern from "compress.h":

    size_t compress(void *s_start, void *d_start, size_t s_len)
    size_t decompress(void *s_start, void *d_start, size_t s_len, size_t d_len)
    uint32_t checksum32(void *cp_arg, size_t length)

但在这之后我完全不知道该怎么做 :|


大家帮帮忙吧!=)


编辑:

我遇到了这个错误:

~/essentials/pylzjb# gcc -I /usr/include/python2.6 -shared -o pylzjb.so pylzjb.c compress.c

/usr/bin/ld: /tmp/ccQLZTaG.o: relocation R_X86_64_32S against `_Py_NoneStruct' 
can not be used when making a shared object; recompile with -fPIC
/tmp/ccQLZTaG.o: could not read symbols: Bad value
collect2: ld returned 1 exit status

不过还是谢谢你们 =)

2 个回答

1

看起来谷歌的代码项目pylzjb已经实现了一个Python接口,用来处理compress.c和compress.h文件了?

3

写一个 .pyx 文件,用来封装调用 C 语言的函数?我觉得最难的部分可能是处理缓冲区...

pylzjb.pyx 文件可以长这样(注意你的 .pxd 文件是直接写在里面的):

cdef extern from "compress.h":
    size_t compress(void *s_start, void *d_start, size_t s_len)

from stdlib cimport *

def cmpr(bytes s):
    cdef size_t n = len(s)
    cdef unsigned char *dst = <unsigned char *> malloc(n * sizeof(unsigned char))
    try:
        m = compress(<unsigned char *> s, dst, n)
        ret = [dst[i] for i from 0 <= i < m]
    finally:
        free(dst)
    return ret

编译时使用:

cython -I. pylzjb.pyx
gcc -I /usr/include/python2.5 -shared -o pylzjb.so pylzjb.c compres.c

然后试着用:

import pylzjb
pylzjb.cmpr('asfd')

撰写回答