【前言】:最近在做的工程因为函数是用c写的,但是需要对外提供pyhton接口,研究了一下方法,发现几种方法调用,本文主要是介绍python/c api方法的实现
代码参照:https://github.com/chanzhennan/Extend_Python
【python / c】
python/c调用有三种方法,网上有大量的资料
【python/c api extension】:最多人用的一种方法,python端基本不动,改变c端代码,需要再写接驳函数
【ctypes / cython】:最方便的调用,c端代码不动,python端需要改变大量代码,比如类型,c_int c_float 直接将python改成c风格
【swig】:没用过,第三方库,可以自动大量生成。方便,但是内存容易出错。
我的老大说之前的项目用过swig,但是内存管理就是个噩梦,用起来各种内存报错但是不知道在哪里发生。
【实现】
【c语言函数】
那么我们先有一段简单的c函数,
#sample.h
/* sample.h */
#include <math.h>
extern int gcd(int, int);
extern int in_mandel(double x0, double y0, int n);
extern int divide(int a, int b, int *remainder);
extern double avg(double *a, int n);
typedef struct Point {
double x,y;
} Point;
extern double distance(Point *p1, Point *p2);
#sample.c
/* sample.c */
#include "sample.h"
/* Compute the greatest common divisor */
int gcd(int x, int y) {
int g = y;
while (x > 0) {
g = x;
x = y % x;
y = g;
}
return g;
}
/* Test if (x0,y0) is in the Mandelbrot set or not */
int in_mandel(double x0, double y0, int n) {
double x=0,y=0,xtemp;
while (n > 0) {
xtemp = x*x - y*y + x0;
y = 2*x*y + y0;
x = xtemp;
n -= 1;
if (x*x + y*y > 4) return 0;
}
return 1;
}
/* Divide two numbers */
int divide(int a, int b, int *remainder) {
int quot = a / b;
*remainder = a % b;
return quot;
}
/* Average values in an array */
double avg(double *a, int n) {
int i;
double total = 0.0;
for (i = 0; i < n; i++) {
total += a[i];
}
return total / n;
}
/* Function involving a