【问题标题】:Passing structure with pointers to other structures in ctypes使用指向 ctypes 中其他结构的指针传递结构
【发布时间】:2014-09-13 19:01:33
【问题描述】:

我正在尝试使用 ctypes 为 C 库制作 python 包装器。该库的函数需要一个指向要传递的结构的指针,该指针充当将来调用的句柄。

该结构具有指向另一个内部结构的指针,该结构进一步具有指向其他结构的指针。

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 的经验,所以这可行吗?

【问题讨论】:

    标签: python c ctypes


    【解决方案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

    【讨论】:

    • 谢谢。没错,我创建了 Varnam 类的指针并将其用于函数,而不是指向指针的指针。现在它可以完美运行了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-26
    • 1970-01-01
    • 1970-01-01
    • 2017-01-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多