将ctypes结构传递给cython

时间:2017-05-24 12:11:05

标签: python pointers cython ctypes

我有一个C库(名为clib,标题clib.h),我通过Ctypes调用。函数get_struct返回指向Foo中正向声明的结构clib.h的指针,并且我可以将其他函数调用用作指针(如use_struct(Foo* foo))。我想使用这个指针在Cython中调用相同的函数代码。

由于我不知道结构的内容,我无法在cython中创建重复结构并复制ctypes中的值。所以我想创建一个指向同一内存空间的cython指针,以便调用一些绑定同一API的C代码。

代码大致是这样做的。

在clib.h中:

typedef struct Foo Foo;
Foo * get_struct();
void use_struct(Foo *)

在python方面有ctypes:

# load clib DLL
clib = ctypes.CDLL('clib.so')

# empty Ctypes declaration
class Foo_ct(ctypes.Structure):
    pass

# get and use the struct
clib.get_struct.restype = ctypes.POINTER(Foo_ct)
foo_ct = clib.get_struct()
clib.use_struct(foo_ct)

# call cython code
bar(foo_ct)

在Cython方面,在cylib.pyx:

cdef extern from "clib.h":
    cdef struct Foo:
        pass

    void use_struct(Foo *)


cpdef bar(foo_ct):

    cdef Foo* foo_cy
    foo_cy = <Foo*>&foo_ct  # or something equivalent
    cy_use_struct(foo_cy)

在Cython方面,在cylibc.cpp中:

#import "clib.h"

void cy_use_struct(Foo * foo)
{
    use_struct(foo);
}

这不会在Cannot take address of Python variable行上assigning to 'PyObject *' (aka '_object *') from incompatible type 'void'foo_cy = <Foo*>&foo_ct构建并返回错误。

前进的想法是什么?

1 个答案:

答案 0 :(得分:0)

基于@ oz1和@DavidW评论,以下作品:

from libc.stdint cimport uintptr_t
cdef uintptr_t adr = <uintptr_t>ctypes.addressof(foo_ct.contents)
cy_use_struct(<Foo*>adr)