在python中使用c语言编写的库
本文使用的 cffi 官网网址:https://cffi.readthedocs.io/en/latest/overview.html
cffi 自己本身使用了pycparser 这个库,是用python编写的c语言parser库,官网地址: https://github.com/eliben/pycparser
python被称为是“胶水语言”,号称能够“方便地”调用其他语言,比如c。但是实际操作中,对于非码农出身的人来说写语言接口还是很痛苦的事情。(我就从来没有试图去写过ctype或者swig之类的高级货,一眼看去完全被吓到。)最近发现了一个python模块,“C Foreign Function Interface for Python”(cffi),它把很多低层次的接口都隐藏起来,用户从而不需要写那些让人抓狂的接口文件也能非常方便的调用C语言了。(另外一种方便调用C语言的办法是使用Cython],我有时间会在另一篇文章介绍。)
假设我有一个写好的C语言函数,定义在GSL(GNU Scientific Library)里面的Bessel函数。
- // foo.c
- #include <gsl/gsl_sf_bessel.h>
- double foo(double a, double b){
- return gsl_sf_bessel_J0(a + b);
- }
接下来,我们想在python中用cffi模块调用这个用C语言定义的函数foo
的“签名”,即输入和输出的数据类型。
- # demo_1.py
- from cffi import FFI
- ffi = FFI()
- ffi.cdef("double foo(double, double);")
下一步,我们要把函数foo.c
这个源文件直接传递python 2. 把
# demo_1.py (cont.)
import os
file_dir = os.path.abspath('.')
lib = ffi.verify("#include <foo.c>", include_dirs=[file_dir], libraries=['gsl', 'gslcblas'])
foo
的定义的。它的用法是,用一个string直接告诉python,我要载入foo
定义的C语言源文件。参数foo.c
所在的位置。因为我把foo.c
放在了同一个文件家里,所以我可以用foo.c
的文件夹地址。最后,参数foo
调用了GSL库里面的Bessel函数。 这样就搞定了,我们可以在python中直接调用C语言定义的函数
# demo_1.py (cont.)
a, b = 1.2, 3.4
print lib.foo(a, b)
之前说到第二种传递函数foo
和其他用到的库文件比如GSL“打包”成一个新的库文件,比如叫libfoo.so
而无需再指定其他库文件了。具体方法如下:
- 注意在这一步中我们把gsl和gslclbas这两个库文件“打包”进了
libfoo.so
了。
- # demo_2.py
- from cffi import FFI
- ffi = FFI()
- ffi.cdef("double foo(double, double);")
- import os
- file_dir = os.path.abspath('.')
- lib = ffi.verify("#include <foo.c>", include_dirs=[dir], library_dirs=[dir], libraries=['foo'])
- a, b = 1.2, 3.4
- print lib.foo(a, b)
注意观察library_dirs
用来说明库文件libfoo.so
经常不在系统默认的gsl
等库文件确实一般安装在libraray_dirs
这个参数来指明)。 2. 参数[foo]
,而不是gsl
和libfoo.so
里面。
最后,假如函数foo.h
来包含
// foo.h
#ifndef foo_h__
#define foo_h__
double foo(double, double);
#endif
然后把该头文件传递过去就可以了,即
- , include_dirs=[dir], library_dirs=[dir], libraries=['foo'])
- 配置CFFI接口,参考https://cffi.readthedocs.org/en/latest/installation.html
在python中使用c语言编写的库的更多相关文章
- (转)python中调用R语言通过rpy2 进行交互安装配置详解
python中调用R语言通过rpy2 进行交互安装配置详解(R_USER.R_HOME配置) 2018年11月08日 10:00:11 luqin_ 阅读数:753 python中调用R语言通过r ...
- 如何在python中调用C语言代码
1.使用C扩展CPython还为开发者实现了一个有趣的特性,使用Python可以轻松调用C代码 开发者有三种方法可以在自己的Python代码中来调用C编写的函数-ctypes,SWIG,Python/ ...
- Python中调用c语言(简单版)
Python中有时需要调用c程序中的函数.使用ctype库可以很方便地调用c语言.现说明方法,以及注意事项. c程序编译为.so文件: 我们需要的c语言文件为test.c,要从其中调用func(x,y ...
- Python 中如何自动导入缺失的库?
在写 Python 项目的时候,我们可能经常会遇到导入模块失败的错误:ImportError: No module named 'xxx'或者ModuleNotFoundError: No modul ...
- python中调用C++写的动态库
一.环境:Windows XP + Python3.2 1. dll对应的源文件(m.cpp): #include <stdio.h> extern "C" { _de ...
- VS2017中使用C++语言编写delay函数实现延迟
秒级别的延时 //定义函数 void delay(int sec){ time_t start_time, cur_time; // 变量声明 time(&start_time); do { ...
- 通过编写聊天程序来熟悉python中多线程及socket的用法
1.引言 Python中提供了丰富的开源库,方便开发者快速就搭建好自己所需要的应用程序.本文通过编写基于tcp/ip协议的通信程序来熟悉python中socket以及多线程的使用. 2.python中 ...
- Protobuf在Python中的应用(序列化数据)
1.了解Protobuf Protocol Buffer是Google的语言中立的,平台中立的,可扩展机制的,用于序列化结构化数据 - 对比XML,但更小,更快,更简单.您可以定义数据的结构化,然后可 ...
- python中类似三元表达式的写法
python中没有其它语言中的三元表达式,如: a = x > y ? m : n; python中的类似写法为: a = 1 b = 2 h = "" h = " ...
随机推荐
- OpenCV学习:播放avi视频文件
#if 0 //播放avi视频文件(IplImage) #include <opencv2/opencv.hpp> using namespace std; #pragma comment ...
- OpenCV学习:图像的载入和显示
一.使用IplImage结构读取并显示图像文件: 运行结果: 二.使用Mat类读取并显示图像文件: 使用 Mat 类,内存管理变得简单,不再像使用 IplImage 那样需要自己申请和释放内存,而且一 ...
- [spring] 对实体 "characterEncoding" 的引用必须以 ';' 分隔符结尾
org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 26 in XML document from ...
- shell基础篇(三)--引号
---今天篇幅比较少:只介绍引号. shell中的引号有三种:双引号",单引号',反引号`1. 双引号:由双引号括起来的字符,除$.倒引号(`)和反斜线(\)仍保留其特殊功能外,其余字符均作 ...
- eclipse、tomca和jvm的相关内存配置
1, 设置Eclipse内存使用情况 修改eclipse根目录下的eclipse.ini文件 -vmargs //虚拟机设置 -Xms40m ...
- IntersectRect、wcsrchr、CComPtr、GetFileAttributes
IntersectRect 两矩形相交形成的新矩形 The IntersectRect function calculates the intersection of two source re ...
- [译] 关于CSS中的float和position
原文 http://learn.shayhowe.com/advanced-html-css/detailed-css-positioning 当构建页面排版时,有不同的方法可以使用.使用哪一种方法取 ...
- 【PHP】php 生成条形码
1.什么是条形码? 百度百科定义:条形码(barcode)是将宽度不等的多个黑条和空白,按照一定的编码规则排列,用以表达一组信息的图形标识符.常见的条形码是由反射率相差很大的黑条(简称条)和白条(简称 ...
- ajax 跨域访问 :Access-Control-Allow-Origin
一说到ajax跨域.首先想到的就是jsonp . JSONP方法是一种非官方方法,而且这种方法只支持GET方式,不如POST方式安全. 即使使用jQuery的jsonp方法,type设为POST,也 ...
- java基础---->java输入输出流
今天我们总结一下java中关于输入流和输出流的知识,博客的代码选自Thinking in java一书.我突然很想忘了你,就像从未遇见你. java中的输入流 huhx.txt文件的内容如下: I l ...