经过了前面这么多节课的学习,相信你已经认识到了 C++ 的高效、灵活和强大。使用现代特性,再加上标准库和第三方库,C++ 几乎“无所不能”。
但是,C++ 也有自己的“阿喀琉斯之踵”,那就是语言复杂、学习曲线陡峭、开发周期长、排错 / 维护成本高。
所以,C++ 不能完全适应现在的快速开发和迭代的节奏,最终只能退到后端、底层等领域。要想充分发挥 C++ 的功力,就要辅助其他的语言搭建混合系统,尽量扬长避短,做好那最关键、最核心的部分,这样才能展现出它应有的价值。
由于当前的操作系统、虚拟机、解释器、引擎很多都是用 C 或者 C++ 编写的,所以,使用 C++,可以很容易地编写各种底层模块,为上层的 Java、Go 等语言提供扩展功能。
不过,今天我不去说这些大型语言,而是讲两种轻便的脚本语言:Python 和 Lua,看看 C++ 怎么和它们俩实现无缝对接:以 C++ 为底层基础,Python 和 Lua 作为上层建筑,共同搭建起高性能、易维护、可扩展的混合系统。
Python
Python 应该是除了 JavaScript 以外最流行的一种脚本语言了,一直在 TIOBE 榜单里占据前三名的位置。而且,在新兴的大数据、人工智能、科学计算等领域,也都有着广泛的应用。很多大公司都长期招聘 Python 程序员,就是看中了它的高生产率。
Python 本身就有 C 接口,可以用 C 语言编写扩展模块,把一些低效耗时的功能改用 C 实现,有的时候,会把整体性能提升几倍甚至几十倍。
但是,使用纯 C 语言写扩展模块非常麻烦,那么,能不能利用 C++ 的那些高级特性来简化这部分的工作呢?
很多人都想到了这个问题,于是,就出现了一些专门的 C++/Python 工具,使用 C++ 来开发 Python 扩展。其中,我认为最好的一个就是pybind11。
pybind11 借鉴了“前辈”Boost.Python,能够在 C++ 和 Python 之间自由转换,任意翻译两者的语言要素,比如把 C++ 的 vector 转换为 Python 的列表,把 Python 的元组转换为 C++ 的 tuple,既可以在 C++ 里调用 Python 脚本,也可以在 Python 里调用 C++ 的函数、类。
pybind11 名字里的“11”表示它完全基于现代 C++ 开发(C++11 以上),所以没有兼容旧系统的负担。它使用了大量的现代 C++ 特性,不仅代码干净整齐,运行效率也更高。
下面,我就带你看看怎么用 pybind11,让 C++ 来辅助 Python,提升 Python 的性能。
pybind11 是一个纯头文件的库,但因为必须结合 Python,所以首先要有 Python 的开发库,然后再用 pip 工具安装。
pybind11 支持 Python2.7、Python3 和 PyPy,这里我用的是 Python3:
apt-get install python3-dev
apt-get install python3-pip
pip3 install pybind11
pybind11 充分利用了 C++ 预处理和模板元编程,把原本无聊重复的代码都隐藏了起来,展现了“神奇的魔法”——只需要短短几行代码,就可以实现一个 Python 扩展模块。具体怎么实现呢?
实际上,你只要用一个宏“PYBIND11_MODULE”,再给它两个参数,Python 模块名和 C++ 实例对象名,就可以了。
#include <pybind11/pybind11.h> // pybind11的头文件
PYBIND11_MODULE(pydemo, m) // 定义Python模块pydemo
{
m.doc() = "pybind11 demo doc"; // 模块的说明文档
} // Python模块定义结束
代码里的 pyde