使用 SWIG 为 Python 封装 C/C++ - 第一部分

毫无疑问,C 比 Python 更快,那么像 Numpy 这样的 Python 库是如何如此快速、高效地执行海量数据运算的呢?实际上,像 Numpy 这样的库并不是完全用 Python 编写的,相反,库的某些部分是用 C 编写的,这提供了性能上的提升。在用 C 编写代码后,我们将它们封装在 Python 代码中,这些代码充当了那些 C 代码的接口。然后我们可以使用 Python 语法调用 C 函数,实际的处理过程在后台由 C 完成,结果作为 Python 对象返回。在本文中,我们将看看如何在 Linux 系统上使用名为 SWIG 的软件为我们的 C 程序创建 Python 封装器。

什么是 SWIG

简而言之,SWIG 是一个编译器,它接收 C/C++ 声明并创建所需的包装器,以便从 Python、Tcl、Ruby 等其他语言访问这些声明。

它通常不需要更改现有代码,并能在极短的时间内创建一个接口。

创建封装器的原因

在许多情况下,我们需要封装器,以下是其中几种情况 –

  • 为现有的 C 程序构建解释型接口。
  • 为脚本语言构建高性能的 C 模块。
  • 测试大型 C 程序是一件非常痛苦的事情,所以我们用 Python 等脚本语言编写封装器,因为在这些语言中编写测试非常容易。等等。

安装 SWIG

要直接从 apt 仓库下载 SWIG,请输入以下命令 –

sudo apt-get update
sudo apt-get install swig

使用 SWIG 编写封装器

让我们看看这段 C 代码,它包含两个函数和一个全局变量 –

C


CODEBLOCK_5ce6153d

这是我们的头文件 example.h

C


CODEBLOCK_a3be7398

首先,我们必须创建一个 SWIG 接口文件。该文件包含 ANSI C 函数原型和变量声明。在这里 –

  • %module 指令指定了我们将在 Python 中使用的模块名称。
  • %{ .. %} 块提供了一个位置来插入额外的代码,例如 C 头文件或额外的 C 声明,到生成的包装代码中。
  • %include 指令允许我们包含额外的文件,如头文件。

C


CODEBLOCK_efdbc370

现在我们将使用类似于 $ swig -targetlanguage interfacefile.i 的命令来创建包装代码

$ swig -python example.i

执行此命令后,将创建一个名为 “example_wrap.c” 的包装代码。此文件包含我们原始 C 代码的臃肿版本,其中包含各种错误处理代码等。还会生成另一个文件 “example.py”,这是我们将在 python 脚本中导入的模块。

在此之后,我们必须生成位置无关代码,这些代码将在共享库中使用,方法是使用以下命令编译 “example_wrap.c”“example.c”

$ gcc -c -fpic example_wrap.c example.c -I/use/include/python2.7

将 python2.7 替换为你的 Python 版本。这将生成两个目标文件

“example_wrap.o”“example.o”。在上面的命令中 –

  • -fpic 生成适合在共享库中使用的位置无关代码 (PIC),如果目标机器支持的话。此类代码通过全局偏移表 (GOT) 访问所有常量地址。

注意: 如果你遇到类似 "… ‘Python.h‘ file not found" 的错误,那么可能有以下原因 –

  • 你可能没有 ‘Python.h‘ 文件,或者
  • 你向编译器提供了 ‘Python.h‘ 文件的错误路径

要获取 ‘Python.h‘,你必须使用以下命令安装 Python-dev

$ sudo apt-get install python-dev

要找到 ‘Python.h‘ 的正确路径,请执行以下命令 –

$ python-config --cflags

这将输出类似这样的内容 –

!image

现在将编译命令中的路径替换为这个针对 python2.7 的路径,或者针对 Python 3.5 将版本更改为 python3.5

现在,最后,我们必须将生成的目标文件链接在一起以创建一个共享对象,它类似于 Windows 中的 dll 文件。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。如需转载,请注明文章出处豆丁博客和来源网址。https://shluqu.cn/42600.html
点赞
0.00 平均评分 (0% 分数) - 0