1

我正在围绕 lirc 库创建一个 cython 包装器。我必须按照教程中的描述包装 lirc_config 结构,但我需要将 a 传递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);

这是我的 cython 包装器struct lirc_config

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_configcdef lirc_client.lirc_config *。我似乎无法访问struct lirc_config *.

我尝试过强制转换并将公共标记添加到 _c_lirc_config (如扩展类型文档底部所述)。

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

4

1 回答 1

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

如果这个segfaults,它更多的是原始库的使用问题,而不是Cython问题,我认为......

希望这会有所帮助,如果不与我联系...

于 2013-05-28T03:53:59.413 回答