如何将扩展类型从cython传递到导入的C库

时间:2013-05-27 21:47:17

标签: cython lirc

我正在围绕lirc库创建一个cython包装器。我必须按照the tutorial的描述包装lirc_config结构,但我需要将struct lirc_config *传递给库中的函数。

所以,有问题的结构是(来自/usr/include/lirc/lirc_client.h):

struct lirc_config {
    char *current_mode;
    struct lirc_config_entry *next;
    struct lirc_config_entry *first;

    int sockfd;
};

我需要调用的函数是:

int lirc_code2char(struct lirc_config *config, char *code, char **string);

这是struct lirc_config周围的cython包装器:

cdef class LircConfig:

    cdef lirc_client.lirc_config * _c_lirc_config

    def __cinit__(self, config_file):
        lirc_client.lirc_readconfig(config_file, &self._c_lirc_config, NULL)
        if self._c_lirc_config is NULL:
            raise MemoryError()

    def __dealloc__(self):
        if self._c_lirc_config is not NULL:
            lirc_client.lirc_freeconfig(self._c_lirc_config)

和有问题的一行:

config = LircConfig(configname)
lirc_client.lirc_code2char(config, code, &character)

config需要是结构的指针。这样:

lirc_client.lirc_code2char(&config, code, &character)

给我错误:

cylirc.pyx:76:39: Cannot take address of Python variable

这是有道理的,因为&正在尝试访问LircConfig的地址。

这:

lirc_client.lirc_code2char(config._c_lirc_config, code, &character)

给我错误:

cylirc.pyx:76:45: Cannot convert Python object to 'lirc_config *'

嗯,我以为我将config._c_lirc_config定义为cdef lirc_client.lirc_config *。我似乎无法访问struct lirc_config *

的值

我已尝试投射并将公共标记添加到_c_lirc_config(如Extension types document底部所述)。

我不知道如何调用lirc_code2char函数,因为cython不允许我访问struct lirc_config指针。那里有Cython专家吗?

1 个答案:

答案 0 :(得分:0)

我已经能够编译以下内容而没有任何问题:

#lirc_client.pyx

cdef extern from "lirc/lirc_client.h":
    struct lirc_config:
        pass

    int lirc_readconfig(char *file, lirc_config **config, char *s)
    void lirc_freeconfig(lirc_config *config)

    int lirc_nextcode(char **code)
    int lirc_code2char(lirc_config *config, char *code, char **string)

cdef class LircConfig:

    cdef lirc_config * _c_lirc_config

    def __cinit__(self, config_file):
        lirc_readconfig(config_file, &self._c_lirc_config, NULL)
        if self._c_lirc_config is NULL:
            raise MemoryError()

    def __dealloc__(self):
        if self._c_lirc_config is not NULL:
            lirc_freeconfig(self._c_lirc_config)

    def some_code2char(self, configname):
        cdef char * character
        cdef char * code
        if (lirc_nextcode(&code) == O):
            config = LircConfig(configname)
            lirc_code2char(config._c_lirc_config, code, &character)

这也有效:

def some_code2char(self):
    cdef char * character
    cdef char * code
    if (lirc_nextcode(&code) == O):
        #config = LircConfig(configname)
        lirc_code2char(self._c_lirc_config, code, &character)

注意:不使用.pyd

如果这段错误,更多的是使用原始库,而不是Cython问题,我认为...

希望这有帮助,如果不让我联系......