python C API 是不是与 C++ 完全兼容?

Posted

技术标签:

【中文标题】python C API 是不是与 C++ 完全兼容?【英文标题】:Is the python C API entirely compatible with C++?python C API 是否与 C++ 完全兼容? 【发布时间】:2012-04-28 22:31:40 【问题描述】:

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

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

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

编辑:

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

【问题讨论】:

您应该能够从 C++ 调用 Python C API,但您将无法在 C++ 中编写 Python C 模块。 @DanD。我现在有点困惑,如果你看一下这个页面,docs.python.org/extending/extending.html,它处理的是用 C 或 C++ 扩展 python。我最初的问题可能有点令人费解,所以请允许我改写一下。如果我想用 C++ 编写一个 python 模块,我是否需要做与该页面上的内容不同的事情(除了使用 C++ 结构)?您的回复似乎表明这是不可能的,因此我感到困惑。 @DanD。请详细说明为什么?当然,由于名称修改,任何导出到 Python 的名称都必须在 extern "C" 块中(当然,不能导出 C 无法处理的东西,比如重载),但我不知道有任何其他障碍. 【参考方案1】:

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

例如,从 Python 手册中的Defining New Types 中获取示例代码,它可以用 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 的构造函数和析构函数都不会被调用。 因此,请记住为您的noddy_NoddyType 定义dealloc 函数,您将在其中将value 重置为nullptr。你可能会问,为什么还要费心将值定义为shared_ptr。如果您在 C++ 中使用 Python 扩展(带有异常)来避免类型转换和强制转换、在实现的定义中进行更无缝的集成、基于异常的错误处理可能会更容易等等,这很有用。 尽管 noddy_NoddyType 的对象是由纯 C 实现的机器管理的,但由于 dealloc 函数,value 将根据众所周知的 RAII 规则发布。

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

【讨论】:

首先,非常感谢您详尽而详尽的回答。我完全不知道这些警告!一个简单的问题:使用boost.Python 可以避免其中一些问题吗?有人告诉我,这个库比 Python.h 更适合 C++ 开发。 不客气。是的,当然 Boost.Python 将为您处理几乎所有此类问题。我的示例基于纯 Python C API,但 Boost.Python 在 Python C API 之上为您提供了 C++ 抽象,因此您可以忘记大部分问题。 完美,那么我将开始研究 boost。再次感谢 - 像你这样有用的答案是让我回到 SO 的原因!【参考方案2】:

可以在 C++ 代码中调用 Python C API。 Python C++ 扩展使用与 C 扩展相同的 C API 编写,或者使用一些 3rd 方 API,例如 boost::python。

【讨论】:

太棒了,谢谢!我一定会很快接受你的回答。用 C++ 编码时我必须做些不同的事情吗?

以上是关于python C API 是不是与 C++ 完全兼容?的主要内容,如果未能解决你的问题,请参考以下文章

具有递归的 Python C API - 段错误

是否有可能直接将 C++ 与 Metal API 一起使用

C语言和C++的区别

C++ Windows API - 如何检索字体缩放百分比

AWS greengrass是否完全支持C ++,因为它是python

Python C/API 分配一个 C++ 变量