2014-09-13 116 views
0

我想为使用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的经验,所以这是可行的吗?

回答

1

没有理由在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

+0

谢谢。你是对的,我创建了一个Varnam类的指针,并将其用于该函数,而不是指向指针的指针。现在它完美地工作。 – stc043 2014-09-14 10:32:25