将 ctypes 结构传递给 cython

Pass ctypes structure to cython

我有一个通过 Ctypes 调用的 C 库(名为 clib 和 header clib.h)。函数 get_struct returns 指向结构 Foo 的指针,即 clib.h 中的 forward-declared 并且我可以将其用作其他函数调用的指针(如 use_struct(Foo* foo)).我想用这个指针来调用 Cython.

中的相同函数代码

因为我不知道结构的内容,所以我不能在 cython 中创建一个重复的结构并从 ctypes 中复制值。所以我想创建一个指向相同内存 space 的 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);
}

这不会构建并且 returns 错误 Cannot take address of Python variableassigning to 'PyObject *' (aka '_object *') from incompatible type 'void'foo_cy = <Foo*>&foo_ct.

有什么想法可以推进吗?

根据@oz1 和@DavidW 的评论,以下作品:

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