码迷,mamicode.com
首页 > 编程语言 > 详细

[Python] Python 调用 C 共享库

时间:2014-08-11 10:00:32      阅读:375      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   使用   os   io   文件   

  Linux/Unix 平台下共享库(Shared Library)文件后缀 .so;在 Windows 平台称为动态链接库(Dynamic Link Library),文件名后缀为 .dll。


 

 

利用 ctypes 模块调用 C 共享库

 

  ctypes 是 Python 标准库提供的一个模块,Python 2.3 版本以上支持该模块。ctypes 是 Python 高级外部函数接口,Python 通过它可以调用 C 语言编译的静态链接库和动态链接库。ctypes 支持多个平台,包括 Windows, Windows CE, Mac OS X, Linux, Solaris, FreeBSD, OpenBSD。

 

  ctypes 模块定义了一些基础 C 兼容数据类型,具体类型请点击此处查看。

 

  以下实例演示如何在 Python 程序中使用 ctypes 模块来调用 C 程序函数。

 

1. 准备 C 程序源文件 sum.c

 

  在 sum.c 源文件定义一个 sum() 函数,用以计算 N 个连续自然数之和。

#include <stdio.h>

int main(void){
    int x;
    printf("Input an integer:\n");
    scanf("%d", &x);
    printf("sum=%d\n", sum(x));
    return 0;
};

int sum(int x){
    int i, result=0;
    for(i=0; i<=x; i++){
        result+=i;
    }
    return result;
};

 

2. 将 C 源代码编译成共享库文件 sum.so

 

  使用 gcc 编译器将 sum.c 编译为共享库文件 sum.so。

$ gcc sum.c -fPIC -shared -o sum.so

 

3. 准备 Python 模块 sum.py

 

  在 sum.py 模块中我们定义一个 py_sum() 函数,该函数是 sum.c 文件中 sum() 函数的 Python 实现。

#!/usr/bin/env python
# -*- coding: utf8 -*-

import ctypes

so = ctypes.CDLL(./sum.so)

def display_dict():
    print "Type of so is %s" % type(so)
    print "Attributes before calling so.sum: %s" % dir(so)
    print "so.sum(10) = %s" % so.sum(10)
    print "Attributes after calling so.sum: %s" % dir(so)


def py_sum(x):
    y = 0
    for i in range(x+1):
        y += i
    return y


def so_sum(x):
    return so.sum(x)


if __name__ == "__main__":
    pass

 

  在 Python 模块中 import ctypes,然后通过 ctypes.CDLL() 方法导入共享库文件 sum.so,之后就可以直接调用动态库提供的函数。

  

4. 测试 Python 调用共享库

 

  让我们在 __main__ 区块中调用 display_dict 函数:

if __name__ == "__main__":
    display_dict()

 

  运行 sum.py 查看结果:

$ python sum.py
Type of so is <class ctypes.CDLL>
Attributes before calling so.sum: [_FuncPtr, __class__, __delattr__, __dict__, __doc__, __format__, __getattr__, __getattribute__, __getitem__, __hash__, __init__, __module__, __new__, __reduce__, __reduce_ex__, __repr__, __setattr__, __sizeof__, __str__, __subclasshook__, __weakref__, _func_flags_, _func_restype_, _handle, _name]
so.sum(10) = 55
Attributes after calling so.sum: [_FuncPtr, __class__, __delattr__, __dict__, __doc__, __format__, __getattr__, __getattribute__, __getitem__, __hash__, __init__, __module__, __new__, __reduce__, __reduce_ex__, __repr__, __setattr__, __sizeof__, __str__, __subclasshook__, __weakref__, _func_flags_, _func_restype_, _handle, _name, sum]

 

  从结果可以发现 .so 共享库导入到 .py 模块中得到一个 ctypes.CDLL 对象。调用了 C 函数之后,CDLL 对象会将该函数添加到对象属性中。(在调用 sum 函数之后,CDLL 对象属性列表中才包含了 sum 函数。)

 

5. Python 调用共享库的性能

 

  我们修改一下 sum.py 模块:

if __name__ == "__main__":
    import timeit
    i = 10000
    print "py_sum(%s) = %s" % (i, py_sum(i))
    print "so_sum(%s) = %s" % (i, so_sum(i))

    print timeit.timeit("py_sum(10000)", setup="from __main__ import py_sum", number=1000)
    print timeit.timeit("so_sum(10000)", setup="from __main__ import so_sum", number=1000)

 

  查看运行结果:

$ python sum.py
py_sum(10000) = 50005000
so_sum(10000) = 50005000
6.82061600685
0.158802986145

 

  以上测试显示,循环叠加 10000 次,执行代码 1000 次,Python 代码耗费了 6.820 秒,C 代码耗费了 0.158 秒,Python 代码耗费时间是 C 代码耗费时间的 42.95 倍。

 

[Python] Python 调用 C 共享库,布布扣,bubuko.com

[Python] Python 调用 C 共享库

标签:style   blog   http   color   使用   os   io   文件   

原文地址:http://www.cnblogs.com/ifantastic/p/3903446.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!