想在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 == NULLreturn;
     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 == NULLreturn;
    v->x  += s;
    v->y  += s;
    v->z  += s;
}

void  subScalar(Vec3 * v,  double s){
     if(v == NULLreturn;
     addScalar(v,  -s);
}

void  mulScalar(Vec3 * v,  double s){
     if(v == NULLreturn;
    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函数了。






愚人节快乐!