想在python中无痛地调用C语言吗?
快用cffi吧!
下面我给大家演示一下,python是如何通过cffi调用c程序的。
首先,我自己写了个三维向量结构体:Vec3.
具体分为两个文件: vect3.h 和 vect3.c.
vect3.h如下:
#define HELLO 3
typedef struct
{
double x;
double y;
double z;
char * label;
}Vec3;
Vec3 * getVec3( double x, double y, double z, char * label);
void printVec3(Vec3 * v);
void addScalar(Vec3 * v, double s);
void subScalar(Vec3 * v, double s);
void mulScalar(Vec3 * v, double s);
void divScalar(Vec3 * v, double s);
void extendVec3(Vec3 * v, char c, double s);
void deleteVec3(Vec3 * v);
vect3.c定义为:
#include <stdio.h>
#include <malloc.h>
#include "vect3.h"
Vec3 * getVec3( double x, double y, double z, char * label){
Vec3 * v = (Vec3 *) malloc( sizeof(Vec3));
v->x = x;
v->y = y;
v->z = z;
v->label = label;
return v;
}
void deleteVec3(Vec3 * v){
if (v == NULL) return;
free(v);
v = NULL;
}
void printVec3(Vec3 * v){
if(v == NULL) return;
printf( "x = %.4f , y = %.4f , z = %.4f , label= %s\n ", v->x,v->y,v->z,v->label);
}
void addScalar(Vec3 * v, double s){
if (v == NULL) return;
v->x += s;
v->y += s;
v->z += s;
}
void subScalar(Vec3 * v, double s){
if(v == NULL) return;
addScalar(v, -s);
}
void mulScalar(Vec3 * v, double s){
if(v == NULL) return;
v->x *= s;
v->y *= s;
v->z *= s;
}
void divScalar(Vec3 * v, double s){
if (v == NULL ||!s) return;
v->x /= s;
v->y /= s;
v->z /= s;
}
void extendVec3(Vec3 * v, char c, double s){
if (v == NULL ) return;
switch (c){
case '+':
addScalar(v, s);
break;
case '-':
subScalar(v ,s);
break;
case '*':
mulScalar(v, s);
break;
case '/':
divScalar(v, s);
break;
}
}
int main( int argc, char const *argv[])
{
double x, y, z;
x = 1.0;
y = 2.0;
z = 3.0;
char * label = "ssdf";
Vec3 * v = getVec3(x,y,z,label);
printVec3(v);
addScalar(v, 3.7);
printVec3(v);
deleteVec3(v);
return 0;
}
我们对这个文件进行编译,编译为libvect3.so。这样我们在cffi中就能调用这个动态链接库。
现在我们引入cffi中的FFI类。
from cffi import FFI
ffi = FFI()
此时我们要先定义好这个动态链接库都有什么函数什么常量可以调用。
即,在cffi中使用ffi.cdef这个函数。
ffi.cdef( """
#define HELLO 3
typedef struct
{
double x;
double y;
double z;
char* label;
}Vec3;
Vec3* getVec3(double x, double y, double z, char* label);
void printVec3(Vec3* v);
void addScalar(Vec3* v, double s);
void subScalar(Vec3* v, double s);
void mulScalar(Vec3* v, double s);
void divScalar(Vec3* v, double s);
void extendVec3(Vec3* v, char c, double s);
void deleteVec3(Vec3* v);
""")
这其实就是我们的头文件。
现在可以加载我们的动态链接库。
lib = ffi.dlopen( './libvect3.so')
这时,我们就可以调用C函数了。
愚人节快乐!