本文使用的 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
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 ", 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 ", 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中調用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 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中 ...
python中類似三元表達式的寫法
python中沒有其它語言中的三元表達式,如: a = x > y ? m : n; python中的類似寫法為: a = 1 b = 2 h = "" h = " ...
python中實現三目運算
python中沒有其他語言中的三元表達式,不過有類似的實現方法 如: a = 1 b =2 k = 3 if a>b else 4 上面的代碼就是python中實現三目運算的一個小demo, 如 ...
隨機推薦
SharePoint 2013 Designer系列之數據視圖
在SharePoint使用中,數據展示是一塊很重要的部分,很多時候我們會采用webpart的形式,但是有一些情況,我們不必使用開發,僅需使用Designer即可,下面讓我簡單介紹下數據視圖的使用. 1 ...
AngularJS向指令傳遞數據
我今天要實現的功能是利用AngularJS來完成客戶端過濾器. list.html頁面主要代碼如下: ......
NameValueCollection類
最近在研究HttpRequest類,發現里面的很多屬性都返回一個NameValueCollection對象,今天再來了解一下這個神秘的對象. 隨便寫了個例子,發現跟HashTable類似.但是這個東西 ...
Leaflet學習筆記-基礎內容
為什么選擇Leaflet 開源,且代碼僅有 31 KB,但它具有開發人員開發在線地圖的大部分功能(80%的功能) 是不是比arcgis要小很多呢 官網:http://leafletjs.com/ 劣勢 ...
Java將一個目錄下的所有數據復制到另一個目錄下
/* 將"C:\\JavaProducts\\Source"下的所有數據復制到"C:\\Target"下 */ import java.io.*; public ...
Mqtt服務器搭建
.bg { background: #99CC99 } Mqtt服務器搭建 測試環境:CentOS64位 1.安裝基礎軟件 yum install gcc-c++ yum install cmake ...
SPOJ GSS(Can you answer the Queries)系列 7/8
GSS1 線段樹最大子段和裸題,不帶修改,注意pushup. 然而并不會貓樹之類的東西 #include #define MAXN 50001 using n ...
Maven項目中添加JDBC驅動
在pom.xml配置文件中添加: mysqlmysql-con ...
ARMV8 datasheet學習筆記3:AArch64應用級體系結構之Memory Type and Attributes
1.前言 2. Memory類型和屬性 memory分為normal memory和device memory,兩種類型的Memory有各自的屬性,除了下面介紹的幾種屬性外,還有其他一些雜項屬性 2. ...
Musle比對軟件
下載地址:http://www.drive5.com/muscle/downloads.htm 1)運行: win+R然后輸入cmd,然后cd進入muscle目錄 2) 比對: muscle3.8.3 ...