gpt4 book ai didi

python - 如何在 cython 模块中使用外部包装类?

转载 作者:行者123 更新时间:2023-11-30 03:33:03 25 4
gpt4 key购买 nike

我有一个已经包装好的外部类(我的意思是,它可以通过 python 直接访问而无需进一步的努力),现在我希望它成为更大的 cython 模块的一部分(在换句话说,嵌入它)。

我可以明确地用 python 导入它。但问题是外部类已经在 cython 模块的 extern 函数中使用(因此该类最终在源代码中为 #included)。 Python import 需要编译模块,那么这两个模块可能有同一个类的两个不同拷贝...

然后我应该如何在 cython 中使用外部已经包装的类?


(可能过于简单)示例:

Foo.cpp:

#include "Python.h"
#include "foo.hpp"

struct Foo_wrapper {
PyObject_HEAD
foo bar;
};

static int Foo_init(Foo_wrapper* self, PyObject* args, PyObject*) {
....
}

static PyTypeObject FooType {...};

垃圾邮件.pyx:

cdef extern from "some_functions.hpp":
cdef some_function1(some_type); // this returns a wrapped foo object

def spam(arg1, arg2, arg3):
// wrap arg1, arg2, arg3 to some_type
return some_function1(an_instance_of_some_type); // huh? but foo isn't available here!

我想在 spam.pyx 中使用 foo 类。

最佳答案

这应该(几乎)没问题。此 cdef extern 行不太正确:

cdef extern from "some_functions.hpp":
object some_function1(some_type); // this returns a wrapped foo object

注意 object 的变化 - 这告诉 Cython 该函数返回一个 Python 对象。 C/C++ 声明如下所示:

PyObject* some_function1(some_type);
// or
Foo_wrapper* some_function1(some_type);

两者都行。

Cython 代码可以正常运行的原因是 PyObject_HEAD 包含一个指向 PyTypeObject FooType 的指针 ob_type。这是在创建对象时设置的。 PyTypeObject 包含 Python 解释器使用返回对象所需的所有详细信息,因此一切都应该正常工作。


整个事情基本上等同于 Python 代码:

# in "somemodule.py"
def a_function():
import something_else
return something_else.Class()

Python 解释器可以使用返回值,尽管 Class 在“全局”命名空间中未知。


需要注意的一点是,在创建Foo_wrapper 之前,您应该确保至少调用了一次Foo 模块初始化函数。原因是此函数通常会执行一些操作,例如调用 PyType_Ready(&FooType) 以确保正确设置 FooType。一种简单的方法是将以下行添加到 some_function1:

PyObject* m = PyImport_ImportModule("Foo");
if (m==NULL) return NULL; // an error
Py_CLEAR(m); // don't need to keep a reference to it

不过还有其他方法可以做同样的事情。

关于python - 如何在 cython 模块中使用外部包装类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43227184/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com