通过ctypes中其他结构的指针传递结构
问题描述:
我想为使用ctypes的C库做一个python包装。该库具有需要指向要传递的结构的指针的函数,该指针充当未来调用的句柄。通过ctypes中其他结构的指针传递结构
该结构具有指向另一个内部结构的指针,该内部结构还具有指向其他结构的指针。
typedef struct varnam {
char *scheme_file;
char *suggestions_file;
struct varnam_internal *internal;
} varnam;
varnam_internal
该结构具有指针SQLite数据库等等
struct varnam_internal
{
sqlite3 *db;
sqlite3 *known_words;
struct varray_t *r;
struct token *v;
...
}
我试图根据this SO回答忽略varnam_internal结构。像
class Varnam(Structure):
__fields__ = [("scheme_file",c_char_p),
("suggestions_file",c_char_p),("internal",c_void_p)]
但是这样的东西似乎并没有工作,因为我觉得库需要分配varnam_internal
,才能正常运行。
我应该在Python中实现所有的依赖结构吗? ctypes适合包装这样的图书馆吗?我已经阅读了像Cython这样的替代品,但是我没有使用Cython的经验,所以这是可行的吗?
答
没有理由在ctypes中定义varnam_internal
结构,因为您应该无需访问它。无论您是否定义结构,您调用的库都将分配它。无论遇到什么问题,都不是因为你没有在ctypes中定义结构。
确保您正确地呼叫varnam_init
。它使用指针作为参数的指针,这意味着你不能直接使用你的类Varnam
。你会希望做这样的事情:
from ctypes import *
class Varnam(Structure):
__fields__ = [("scheme_file",c_char_p),
("suggestions_file",c_char_p),
("internal",c_void_p)]
varnam_ptr = POINTER(Varnam)
libvarnam = cdll.LoadLibrary("libvarnam.so") # on Linux
# libvarnam = cdll.libvarnam # on Windows
varnam_init = libvarnam.varnam_init
varnam_init.argtypes = [c_char_p, POINTER(varnam_ptr), POINTER(c_char_p)]
def my_varnam_init(scheme_file):
handle = varnam_ptr()
msg = c_char_p()
r = varnam_init(scheme_file. handle.byref(), msg.byref())
if r != 0:
raise Exception(msg)
return handle
上面的代码是经过充分测试,但显示您应该如何调用varnam_init
。
谢谢。你是对的,我创建了一个Varnam类的指针,并将其用于该函数,而不是指向指针的指针。现在它完美地工作。 – stc043 2014-09-14 10:32:25