如何为Cython创建具有依赖项的单独文件以及如何修复编译错误:无法将Python对象转换为“mySet *”

时间:2011-11-06 04:03:51

标签: python cython python-extensions

我正在尝试使用Cython构建我的fisrt python扩展。

我的C文件在逻辑上是分区的,并且功能是“嵌套的” - 模块C依赖于模块B中定义的函数,然后模块B依赖于模块A.

我发现很难理解如何对.pxd和.pyx文件进行分区,以便我可以维护功能模块之间的依赖关系。

以下片段,希望有助于澄清情况:

注意:文件FooBar.h包含一个CommonDefs.h文件,它声明了常见的数据类型,并为这些常见类型(myArray和mySet)提供了一个简单的API。

我已经创建了ccommontypes.pxd和commontypes.pyx文件,这些文件导出在CommonDefs.h和CommonDefs.c中声明/定义的数据类型和函数。我能够从那里成功编译一个python扩展模块。

我现在想进入下一个阶段,即导出依赖于CommonDefs.h的数据类型和函数。但是,我发现我必须重新声明这些类型 myArray和mySet(即使它们已经在ccommontypes.pxd

中声明了

我似乎无法找到导入或包含这些声明的内容,所以我不得不在下面的文件中重新声明它们,因为函数接受myArray和mySet类型的参数。

问题1 如下所述,是否可以重新声明类型,或者我需要注意哪些问题?

//cfoobar.pxd
cdef extern from "../include/FooBar.h":
    cdef struct FooBar:
        pass

    ctypedef struct myArray:   // already declared elsewhere
        pass

    ctypedef struct mySet:     // Already declared elsewher
        pass

    struct FooBar * foobar_new(mySet *s1)


//foobar.pyx
cimport cfoobar

cdef class FooBar:
    cdef cfoobar.FooBar *_foobar
    def __cinit__(self, myset):
        _foobar = cfoobar.foobar_new(myset);
        if (ret == 0):
            raise MemoryError()

问题2 从上面的FooBar代码中,内存分配函数需要一个指向mySet变量的指针。但是,当我尝试编译此代码时,我收到此错误:

无法将Python对象转换为“mySet *”

我理解错误消息,但由于Python不是静态类型,我不知道如何指定数据类型。

我希望得到一些解决这个问题的帮助。

1 个答案:

答案 0 :(得分:0)

我在尝试自己解决pxds中的重新声明问题时遇到了这个问题......我相信必定会有一些“陷阱”,但我不敢冒险说出它们是什么。 :)

但问题2:python是动态类型的,但是cython不是......只是没有类型的变量被静态类型化为python对象。

您可以更改:

def __cinit__(self, myset):

为:

def __cinit__(self, mySet *myset):

如果你真的传递指向myset的指针......