1

据我了解C和C++之间的关系,后者本质上是前者的扩展,并且保留了一定程度的向后兼容性。假设可以使用 C++ 代码调用 python C API 是否安全?

更重要的是,我注意到官方 python 文档将 C 和 C++ 扩展捆绑在同一页面上。我在任何地方都找不到 C++ API。这让我相信相同的 API 在两种语言中都可以安全使用。

有人可以确认或否认这一点吗?

编辑:

我想我让我的问题比它需要的复杂得多。问题是:我必须做什么才能用 C++ 编写 python 模块?我是否只是按照此处列出的相同指示,用 C 代码代替 C++?有单独的 API 吗?

4

2 回答 2

4

我可以确认在 C 和 C++ 这两种语言中使用相同的 Python C API 是安全的。但是,除非您提出更具体的问题,否则很难为您提供更详细的答案。您应该注意许多警告和问题。例如,您的 Python 扩展被定义为 C 类型 struct,而不是 C++,因此不要期望它们的构造函数/析构函数被隐式定义和调用

例如,从Python 手册中的定义新类型中获取示例代码,它可以用 C++ 方式编写,您甚至可以混合 C++ 类型:

// noddy.cpp
namespace {

struct noddy_NoddyObject
{
    PyObject_HEAD
    // Type-specific fields go here.
    std::shared_ptr<int> value; // WARNING
};

PyObject* Noddy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    try {
        Noddy *self = (Noddy *)type->tp_alloc(type, 0);
        if (self) {
            self->value = std::make_shared(7);
            // or more complex operations that may throw
            // or extract complex initialisation as Noddy_init function
            return self;
        }
    }
    catch (...) {
        // do something, log, etc.
    }
    return 0;
}

PyTypeObject noddy_NoddyType =
{
    PyObject_HEAD_INIT(NULL)
    // ...
}

} // unnamed namespace

但是,不会std::shared_ptr调用 的构造函数和析构函数。因此,请记住为您将重置with的位置定义dealloc函数。您可能会问,为什么还要费心将值定义为。如果您在 C++ 中使用 Python 扩展(有异常)来避免类型转换和强制转换,在实现的定义中实现更无缝的集成,基于异常的错误处理可能会更容易等等,这很有用。尽管有事实上,你的对象是由纯 C 实现的机器管理的,这要归功于函数将根据众所周知的 RAII 规则发布。noddy_NoddyTypevaluenullptrshared_ptrnoddy_NoddyTypedeallocvalue

在这里,您可以找到 Python C API 与 C++ 语言几乎无缝集成的有趣示例:How To catch Python stdout in c++ code

于 2012-04-28T22:50:07.780 回答
1

Python C API can be called within C++ code. Python C++ extensions are written using the same C API as C extensions use, or using some 3rd party API, such as boost::python.

于 2012-04-28T22:41:57.073 回答