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++ 完全兼容?的主要内容,如果未能解决你的问题,请参考以下文章