page contents

python和C语言互相调用的几种方式

Python这些年风头一直很盛,占据了很多领域的位置,Web、大数据、人工智能、运维均有它的身影,甚至图形界面做的也很顺,乃至full-stack这个词语刚出来的时候,似乎就是为了描述它。 Python虽...

Python这些年风头一直很盛,占据了很多领域的位置,Web、大数据、人工智能、运维均有它的身影,甚至图形界面做的也很顺,乃至full-stack这个词语刚出来的时候,似乎就是为了描述它。

Python虽有GIL的问题导致多线程无法充分利用多核,但后来的multiprocess可以从多进程的角度来利用多核,甚至affinity可以绑定具体的CPU核,这个问题也算得到解决。虽基本为全栈语言,但有的时候为了效率,可能还是会去考虑和C语言混编。

混编是计算机里一个不可回避的话题,涉及的东西很多,技术、架构、团队情况、管理、客户等各个环节可能对其都有影响,混编这个问题我想到时候再开一贴专门讨论。本文只讲python和C混编的方式,大致有如下几种方式(本文背景是linux,其他平台可以类比):

共享库

使用C语言编译产生共享库,然后python使用ctype库里的cdll来打开共享库。

举例如下,C语言代码为

v2-dacc654bdd0aaa947591790bb00fbd25_hd.jpg

python代码为

v2-8903cf6e1663a41f3cb56e57d1d2d691_hd.jpg

测试如下

v2-58fac80598345fbea99b283583085500_hd.jpg


subprocess

C语言设计一个完整的可执行文件,然后python通过subprocess来执行该可执行文件,本质上是fork+execve。

举例如下,C语言代码为

v2-4130098b867081f4754d0af1e12da05a_hd.jpg

Python代码为

v2-c7744ea342ec2422fc83c491bae2010d_hd.jpg

测试如下

v2-5159184bbf233a4da3192d224ff1b59c_hd.jpg

C语言中运行python程序

C语言使用popen/system或者直接以系统调用级fork+exec来运行python程序也是一种混编的手段了。

举例如下,Python代码如下

v2-fe8688538127a7f9938df610811846a9_hd.jpg

C语言代码如下

v2-eda12c2a34d753b5edaed5f427a970ce_hd.jpg

测试如下

v2-e5fbc86434eca98de56369e476bd69eb_hd.jpg


Python对C语言扩展的支持

很多编程语言都为C语言扩展添加了支持,这有两种原因:(1)语言设计之初,可以充分的利用C语言已有的库来做很多扩展;(2)C语言的运行效率高。

python也不例外,从诞生那天起,很多库都是C语言写的。python的C语言扩展中涉及到python的数据结构与C语言的对应,扩展方法其实是用C语言编写一个共享库,只是这个共享库中的接口是一个规范的,可以被python识别的。

为了说明如何扩展,我这里先假设一个在python下的函数功能,代码如下

v2-5ad9db982a3ad9d3246a656c765ef55b_hd.jpg

如上,希望的函数功能是,参数是任意多个数字组成的列表(姑且排除其他数据结构),返回每个列表的元素之和的乘积。

姑且先把python代码写了,如下所示

v2-fd575d28c85f3ac43eb796bd1ff6904d_hd.jpg

带上之前一直测试的平方func,这个实现相对简单,希望python写出来的func可以和C语言扩展出来的结果一致。

先用C语言写上这些函数的实现,其中func3用上了一个表示任意多个任意长的数组的数据结构y_t,而x_t用来表示单个数组。

v2-49b6cea610437df724ca52086b6954e0_hd.jpgv2-dc63dcedd71f2cc1392a4eac27ae74b6_hd.jpg

上面定义了三个函数,func2代表平方,func3代表之前所说的功能,又因y_t这个结构可能都是动态分配出来的,所以给个归还内存的方法。

刚才说过python扩展的话,需要把这个共享库的接口“标准化”一下。于是我们就包装一下,并给个python加载的入口。

v2-655db5c841ac17a5e75de4c783b5cced_hd.jpgv2-347f4621bb491f820115452b26289e2f_hd.jpgv2-e76106bace5376e1c08fd7811f428dde_hd.jpg

过程中,我猜测PyArg_VaParse应该功能更为强大,可是反复测没有成功,也没细看文档。

测试一下

v2-ab4a9eecc87cc52716b68cdbef5359cf_hd.jpg

可以看到,C语言写的函数和python写的函数结果一致。

  • 发表于 2020-02-17 15:20
  • 阅读 ( 591 )
  • 分类:Python开发

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
Pack
Pack

1135 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1312 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章