[Python] Python 调用 C 共享库

  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 共享库

时间: 2024-10-11 05:28:13

[Python] Python 调用 C 共享库的相关文章

使用ctypes在Python中调用C++动态库

使用ctypes在Python中调用C++动态库 入门操作 使用ctypes库可以直接调用C语言编写的动态库,而如果是调用C++编写的动态库,需要使用extern关键字对动态库的函数进行声明: #include <iostream> using namespace std; extern "C" { void greet() { cout << "hello python" << endl; } } 将上述的C++程序编译成动态链

使用ctypes调用C共享库中函数返回值为链表式结构时的方法

/*********************************************************************  * Author  : Samson  * Date    : 02/02/2015  * Test platform:  *              3.13.0-24-generic  *              GNU bash, 4.3.11(1)-release  * ************************************

android开发调用c++共享库so文件

1.编写libaab.cpp #include <stdio.h>#include <stdlib.h> #ifdef __cplusplusextern "C" {#endif int go() { return 555; } #ifdef __cplusplus}#endif 运行g++命令编译得到libaab.so arm-linux-androideabi-g++.exe -I/usr/local/linux-androideabi/platforms/

QT共享库的创建与调用(初级)

背景: 最近在做的一个项目其中一部分既是实现PC与下位机的USB通信.windows平台下已经完成,现需移植到linux平台下. 在linux系统中,通过一段时间的工作,设备已被配置成hid类(后续再详述),并以hidraw类设备节点存在于系统中"/dev/"下.上位机则成功在console中通过调用HIDAPI库来写入.读取hidraw设备节点信息(后续再详述),而进一步的图形界面则需由QT来完成. hidraw设备介绍: https://www.kernel.org/doc/Doc

共享库文件ldconfig 配置导致*.so找不到

error whilel oading shared libraries:libluajit-5.1.so.2: cannot open shared解决办法 一般我们在Linux下执行某些外部程序的时候可能会提示找不到共享库的错误, 比如: tmux: error while loading shared libraries: libevent-1.4.so.2: cannot open shared object file: No such file or directory 原因一般有两个

一个简单的C共享库的创建及python调用此库的方法

/*********************************************************************  * Author  : Samson  * Date    : 02/02/2015  * Test platform:  *              3.13.0-24-generic  *              GNU bash, 4.3.11(1)-release  * ************************************

『Python CoolBook』C扩展库_其六_从C语言中调用Python代码

一.C语言运行pyfun的PyObject对象 思路是在C语言中提供实参,传给python函数: 获取py函数对象(PyObject),函数参数(C类型) 获取GIL(PyGILState_Ensure) 确保fun对象可调用 参数转换为python对应类型(Py_BuildValue) 调用python函数(PyObject_Call) 确定调用无异常 检查返回值 释放GIL(PyGILState_Release) 异常处理 #include "Python.h" /* Execut

用python的matplotlib和numpy库绘制股票K线均线和成交量的整合效果(含量化验证交易策略代码)

在用python的matplotlib和numpy库绘制股票K线均线的整合效果(含从网络接口爬取数据和验证交易策略代码)一文里,我讲述了通过爬虫接口得到股票数据并绘制出K线均线图形的方式,在本文里,将在此基础上再引入成交量效果图,并结合量价理论,给出并验证一些交易策略. 1 成交量对量化分析的意义 美国的股市分析家葛兰碧(Joe Granville)在他所著的<股票市场指标>一书里提出著名的“量价理论”.“量价理论”的核心思想是,任何对股价的分析,如果离开了对成交量的分析,都将是无本之木,无水

【Python网页分析】httplib库的重定向处理

1. 网页处理 下图是实际操作抓包分析结果,其他的步骤不再描述. 1.从选定的POST /main.aspx开始 2.后面服务器回复302重定向到/cd_chose.aspx页面 3.抓包数据有GET重定向URL,GET css和js文件不再赘述 4.POST到/cd_chose.aspx 2. Python模拟 2.1 抓包分析,后面的GET方法发送不去 再查看IE上抓包结果 没有出现GET方法 怀疑是需要直接POST,尝试了之后仍然失败,但仔细看了下POST内容,头里面有GET头,由于不太了