# 简介

开发一个程序时,一般只使用一种编程语言,如果想混合使用其它语言,怎么办?

  • 可以用其它语言编写另一个程序,编译成可执行文件,供当前程序调用。
  • 可以用其它语言编写另一个程序,运行成为一个独立进程,与当前程序进行网络通信(比如 HTTP 通信),从而协同工作。
  • 可以用其它语言编写一段代码(比如一个函数、一个类),被当前程序调用。本文介绍这种情况。

CPython 是基于 C 语言实现的一款 Python 解释器,因此它支持 Python 与 C/C++ 的混合开发。

  • 从 Python 调用 C/C++ 代码,有两种方式:
    • 把 C/C++ 代码编译成 C/C++ 的动态链接库,再被 Python 导入。
    • 把 C/C++ 代码封装成 Python 的扩展模块,再被 Python 导入。
  • 从 C/C++ 调用 Python 代码,有两种方式:
    • 把 Python 代码转换成 C/C++ 的动态链接库,再被 C/C++ 导入。
    • 把 Python 代码转换成 C/C++ 的源文件,再被 C/C++ 导入。

# 混合开发工具

混合开发工具有多种,选择它们时需要从多方面考虑,比如:

  • 是否支持从 C/C++ 调用 Python ?或者反之?
  • 如何从 Python 传递一份数据到 C/C++ ?应该采用 Python 的哪种数据类型?转换成 C/C++ 的哪种数据类型?
    • 反之,如何从 C/C++ 传递一份数据到 Python ?
    • 进一步地,哪些数据类型可以通用?哪些数据类型不兼容?
  • 能否调用函数?这样更方便。
  • 能否调用类?这样更方便。
  • 最终开发的程序,能否移植到 Linux、Windows、MacOS 等多种平台?

# CPython API

  • 优点:
    • 它是 CPython 解释器自带的功能,不需要安装第三方库。
    • 它是实现 Python 混合开发的底层 API ,是其它混合开发工具的基础。
    • 它可以将 C/C++ 代码封装成 Python 模块,或者将 Python 代码封装成 C 代码。
  • 缺点:
    • 只提供了底层 API ,直接使用的话很麻烦。

# ctypes

  • 优点:
    • 它是 Python 自带的标准库,不需要安装第三方库。
    • 支持从 Python 加载 C 的动态链接库,直接调用其中的函数。或者将 Python 函数作为回调函数传给 C 函数。
    • 使用时不需要封装 C 代码,可以直接调用 C 的动态链接库。
  • 缺点:
    • 没有封装 C 函数,因此 Python 调用一个 C 函数时需要自己转换数据类型。
    • 只支持 C 语言,因此调用 C++ 代码时,需要先封装成 C 函数。
    • 不支持从 C/C++ 主动调用 Python 代码。

# Cython

  • :Python 的第三方库,可以将 C 代码封装成 Python 模块,或者将 Python 代码编译成 C 代码。
  • 注意区分:CPython 是一个 Python 解释器,Cython 是一个 Python 库。
  • 优点:
    • 可以在 Python 中使用 C/C++ 的数据类型、函数,扩展 Python 的语法,提高 Python 程序的运行效率。

# SWIG

  • :一个编译器,可以将 C/C++ 代码封装成供 C#、Java、Python 等多种语言调用的文件。
  • 缺点:
    • 不支持从 C/C++ 主动调用 Python 。

# Boost.Python

  • :一个 C++ 库,可以将 C++ 代码封装成 Python 模块,或者在 C++ 中导入 Python 模块。
  • Boost 库的使用很广,提供了一些扩展功能的 C++ 库,近乎 C++ 的标准库。

# pybind11

  • :一个 C++ 库,相当于轻量级的 Boost.Python 。
  • 优点:
    • 比较简单,使用时只需要导入一个头文件。但功能完备。
    • 对 C/C++ 代码的封装比较完善,能加上模块说明、函数说明。