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

发布于 2024-12-13 22:09:09 字数 1429 浏览 2 评论 0原文

我正在尝试使用 Cython 构建我的第一个 python 扩展。

我的 C 文件按逻辑分区,并且功能是“嵌套”的 - 在模块 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 ctor 代码来看,内存分配函数需要一个指向 mySet 变量的指针。但是,当我尝试编译此代码时,出现此错误:

Cannot conversion Python object to 'mySet *'

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

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

I am trying to build my fisrt python extension, using Cython.

My C files are partitioned logically, and the functionality is "nested" - in that module C depends on functions defined in module B, which then depends on module A.

I am finding it difficult to understand how to partition my .pxd and .pyx files so that I can maintain the depency between functional modules.

The following snippet, hopefully should help clarify the situation:

Note: The file FooBar.h includes a file CommonDefs.h which declares common data types and provides a simple API for these common types (myArray and mySet).

I have already created ccommontypes.pxd and commontypes.pyx files which export the data types and functions declared/defined in CommonDefs.h and CommonDefs.c. I was able to succesfully compile a python extension module from that.

I now want to move to the next stage which is to export the data types and functions which have a dependency on CommonDefs.h. However, I find that I am having to redeclare the types
myArray and mySet (even though they were already declared in ccommontypes.pxd

I can't seem to find anyway of importing or including those declarations, so I am having to re-declare them in the file below, as the functions take arguments of type myArray and mySet.

Question 1
Is it ok to redeclare the types again as I have done below or are there any gotchas I need to be aware of?

//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()

Question 2
From the FooBar ctor code above, the memory allocation function expects a pointer to a mySet variable. However, when I attempt to compile this code, I get this error:

Cannot convert Python object to 'mySet *'

I understand the error message, but since Python is not statically typed, I don't know how I can specify the data type.

I would appreciate some help on resolving this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

风月客 2024-12-20 22:09:09

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

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

您可以将:更改

def __cinit__(self, myset):

为:

def __cinit__(self, mySet *myset):

如果您确实传递了指向 myset 的指针...

I came across this question while trying to sort out redeclaration issues in pxds myself... I believe there must be some "gotchas" but I won't venture yet to say what they are. :)

But to question 2: python is dynamically typed but cython is not ... just that variables without types are statically typed as python objects.

You can change:

def __cinit__(self, myset):

to:

def __cinit__(self, mySet *myset):

if you are really passing in a pointer to a myset...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文