浅谈 Python 程序和 C 程序的整合(3)

from ctypes import cdll # 首先导入 ctypes 模块的 cdll 子模块,注意 linux 平台上使用 cdll 的,而不是 windll。 somelibc = cdll.LoadLibrary(“./some.so”) # 使用 cdll 模块的 LoadLibrary 导入动态链接库

访问动态链接库中的函数 清单 10. ctypes 使用 so 中的函数

somelibc. helloworld() # 使用方法与 windows 平台上是一样的。

整个 helloworld.py 是这样的:

清单 11. Python helloworld 代码

from ctypes import cdll def callc(): # load the some.so somelibc = cdll.LoadLibrary(some.so) print somelibc. helloworld() if __name__== “__main__”: callc()

在命令行运行 helloworld.py,在 linux 标准输出上可以看到 some.so 中 helloworld 的输出。

清单 12. Python hellpworld Linux shell 运行输出

[root@linux-790t] python ./helloworld.py Hello World! Just a simple test.

Python 程序和 C 程序整合实例

以下我们举例用 Python 来实现一个小工具,用来实现 hash 算法,查看文件的校验和(MD5,CRC,SHA1 等等)。通过查看文件的校验和,可以知道文件在传输过程中是否被破坏或篡改。

Hash,一般翻译做“散列”,也有直接音译为"哈希"的,就是把任意长度的输入(又叫做预映射,pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,而不可能从散列值来唯一的确定输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。

由于相对 C 语言来说,Python 的运行效率较低,因此我们的 Python 小工具利用一个已有的 C 语言的动态链接库 (hashtcalc.dll) 来实现我们的程序。本例中,我们运用 wxPython 编写简单的 GUI 界面,通过 python 调用 hashtcalc.dll 的接口计算文件的校验和,然后输出在界面上。

架构图 图 1. 工具的架构图

图 1. 工具的架构图

hashcalc.dll 接口描述

函数名:calc_CRC32

函数:char* calc_CRC32(char *filename);

参数:文件名

返回值:字符串

说明:该函数对输入的文件内容进行计算,并且返回它的 CRC32

函数名:calc_MD5

函数:char* calc_MD5(char *filename);

参数:文件名

返回值:字符串

说明:该函数对输入的文件内容进行计算,并且返回它的 MD5

函数名:calc_SHA1

函数:char* calc_SHA1 (char *filename);

参数:文件名

返回值:字符串

说明:该函数对输入的文件内容进行计算,并且返回它的 SHA1

HashcalcAdapter 代码

HashcalcAdapter.py 实现了一个 python 的 class HashcalcAdapter,HashcalcAdapter 对 hashtcalc.dl 的 C 语言接口进行了封装,使得其他 python 模块可以直接通过 HashcalcAdapter 使用 hashtcalc.dll 中实现的 hash 算法。具体的代码如下:

清单 13. HashcalcAdapter.py 代码

from ctypes import windll from ctypes import * class HashcalcAdapter(object): def __init__(self, dllpath): self._dllpath = dllpath self._libc = windll.LoadLibrary(self._dllpath) def calc_CRC32(self, filename): new_filename = c_char_p(filename) return self._libc.calc_CRC32(new_filename) def calc_MD5(self, filename): new_filename = c_char_p(filename) return self._libc.calc_MD5(new_filename) def calc_SHA1(self, filename): new_filename = c_char_p(filename) return self._libc.calc_SHA1(new_filename)

运行界面 图 2. 工具的运行界面

图 2. 工具的运行界面

总结

在软件开发过程中同时运用 Python 语言和 C 语言,既能够在加快开发速度的同时,也能够保证软件的运行性能。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/ca2173bbfb7c710eafeb4d8736f308d6.html