本文使用的 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],而不是gsllibfoo.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

最新文章

  1. 一种让 IE6/7/8 支持 media query 响应式设计的方法
  2. CSS生僻问题一网打尽
  3. Winform开发框架之参数配置管理功能实现-基于SettingsProvider.net的构建
  4. HDU 4358 Boring counting(莫队+DFS序+离散化)
  5. js知识体系的梳理一
  6. poj 1505 Copying Books
  7. JSWING小工具
  8. UVA 1386 - Cellular Automaton(循环矩阵)
  9. zabbix 自动发现端口并添加监控设置
  10. [luogu1198][bzoj1012][JSOI2008]最大数【线段树+分块】
  11. 从零开始学 Web 之 移动Web(三)Zepto
  12. JavaWeb学习 (十七)————JSP属性范围
  13. 使用poi读写excel文件
  14. x的奇幻之旅 (史蒂夫&#183;斯托加茨 著)
  15. lodash用法系列(4),使用Map/Reduce转换
  16. fatal One or more refs for names blocks change upload
  17. 双机热备(准)--&gt;RAC(夭折)--&gt;DG(异地容灾)
  18. 0、weka学习与使用
  19. Android Studio 更新失败的解决办法
  20. Java读取大文件的高效率实现

热门文章

  1. VC++ : VS2008 使用ATL开发COM组件
  2. Python 入门(六)Dict和Set类型
  3. hasattr() 、getattr() 、setattr()
  4. lua常用操作
  5. Swift-&#39;!&#39;,&#39;?&#39;用法
  6. linux配置免密登录
  7. js jquery获取当前元素的兄弟级 上一个 下一个元素 jquery如何获取第一个或最后一个子元素
  8. JQuery自定义用户控件方法汇总
  9. OpenLayers基础知识:
  10. MQTT的学习研究(二)moquette-mqtt 的使用之mqtt broker的启动