Python如何嵌入C/C++进行开发?( 二 )


PyString_String()用于将PyObject*类型的变量转换成C语言可以处理的char*型 。具体原型如下:
char* PyString_String(PyObject *p);
其他观点:
如果要在Python中包装现有的C或C ++功能 。则有很多选择可以去做 。一个比较简单的是 。我们可以试着手动封装尝试下如何用Python嵌入C/C++进行开发 。
手动封装
如果您要包装的C / C ++代码相对较少 。则可以手动完成 。文档的“ 扩展和嵌入”部分是一个很好的参考 。
当我为C和C ++代码编写包装器时 。通常会为代码提供一个过程接口 。然后使用Python构造一个面向对象的接口 。我这样做是出于两个原因:首先 。将C ++对象暴露给Python很麻烦;其次 。我更喜欢用Python编写高层结构 。而不是用C ++编写它们 。
让我们看一个基本的包装器:文件“ hello.c”中有一个函数“ hello” 。“ hello”的定义如下:
char * hello(char * what)
要手动封装 。我们需要执行以下操作 。
首先 。编写一个Python可调用函数 。该函数接受一个字符串并返回一个字符串 。

Python如何嵌入C/C++进行开发?

文章插图
Python如何嵌入C/C++进行开发?

文章插图
第三 。为模块编写一个初始化函数(所有扩展模块都需要一个初始化函数) 。
Python如何嵌入C/C++进行开发?

文章插图
第四 。编写一个setup.py脚本:
Python如何嵌入C/C++进行开发?

文章插图
即使在此简单级别上 。此代码也有两个方面值得讨论 。
错误处理
请注意PyArg_ParseTuple调用 。该调用告诉Python 。“ hello”包装函数恰好采用一个参数 。即字符串(“ s”表示“字符串”;“ ss”表示“两个字符串”;“ si”表示“字符串和整数”))。C API与Python的约定是 。从返回PyObject *的函数返回NULL表示已发生错误;在这种情况下 。错误信息是在PyArg_ParseTuple中设置的 。我们只是通过返回NULL在堆栈上传递错误 。
引用计数
Python在引用计数系统上工作:每当一个函数“拥有”一个对象的所有权(例如 。通过将其分配给列表或字典) 。它都会使用Py_INCREF使该对象的引用计数增加1 。当将该对象从该特定位置删除(例如 。从列表或字典中删除)时 。引用计数将使用Py_DECREF减少 。当引用计数达到0时 。Python会知道该对象未被任何对象使用 。并且可以释放该对象(但是 。可能不会立即释放它) 。
为什么这么重要?好吧 。我们正在用PyString_FromString在此代码中创建一个PyObject 。我们需要INCREF吗?要找出答案 。请查看PyString_FromString的文档:
http://docs.python.org/api/stringObjects.html#l2h-461
看到哪里写着“新参考”?这意味着它将交出引用计数为1的对象 。这就是我们想要的 。如果它说“借用的引用” 。那么我们需要在返回对象之前先对对象进行INCREF 。以表明我们希望分配的内存能够在函数结束后继续存在 。
这是一种考虑引用的方法:
如果您从Python API收到Python对象 。则可以在自己的C代码中使用它 。而无需增加它的引用 。
如果您想保证Python对象可以在您自己的C代码末尾保留下来 。则必须INCREF 。
如果您从Python代码收到一个对象 。并且它是一个新引用 。但是您不希望它在您自己的C代码末尾生存下来 。则应该对它进行DECREF 。
顺便说一句 。如果您想返回None 。则可以使用Py_None 。记住要INCREF!
另一个注意事项:我谈到了使用PyCObjects传递不透明的C / C ++数据类型 。如果您使用Python来组织代码 。但是这具有不需要访问Python的复杂结构 。则这很有用 。
您可以将指针包装在PyCObjects中(如果需要 。可以使用关联的析构函数) 。此时它们变为不透明的Python对象 。其内存由Python解释器管理
。可以在示例代码看到一个例子 。下 code/hello/hellmodule.c 。函数cobj_in 。cobj_out以及 free_my_struct 。它通过使用PyCObject包装的分配的C结构回到Python 。
总结
【Python如何嵌入C/C++进行开发?】因此 。这是关于如何手动封装Python的简短介绍 。但是 。您可能会猜到 。有许多项目专门用于自动封装代码 。所以手动封装尝试下用Python嵌入C/C++进行开发 。其他的大家可以搜索看看 。比较好用的是SWIG、pyrex和ctypes的等 。

推荐阅读