我有一个 C 库(称为 clib
,头文件为 clib.h
),我通过 Ctypes
调用它。 。一个函数get_struct
返回指向结构 Foo
的指针这是在 clib.h
中提前声明的我可以将其用作其他函数调用作为指针(如 use_struct(Foo* foo)
)。我想用这个指针来调用 Cython
中相同的函数代码.
由于我不知道结构的内容,因此我无法在 cython 中创建重复的结构并复制 ctypes 中的值。因此,我想创建一个指向相同内存空间的 cython 指针,以便调用一些绑定(bind)相同 API 的 C 代码。
代码大致就是这样做的。
在 clib.h 中:
typedef struct Foo Foo;
Foo * get_struct();
void use_struct(Foo *)
在带有 ctypes 的 python 端:
# 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
.
有什么想法可以继续吗?
最佳答案
根据@oz1和@DavidW评论,以下内容有效:
from libc.stdint cimport uintptr_t
cdef uintptr_t adr = <uintptr_t>ctypes.addressof(foo_ct.contents)
cy_use_struct(<Foo*>adr)
关于python - 将 ctypes 结构传递给 cython,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44158089/