想在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函数了。
愚人节快乐!