一、 简介
Python是个非常流行的解释型脚本语言。而C是一个非常流行的编译语言。由于其编译的性质,导致C一般比Python要快,但是它是更底层的。相对的,Python编程更加快速和简单。故而将C库作为Python库的扩展极为必要,使得Python既融合了自身的优点,又融合了C语言的优点,正是因为这些性质使得Python越来越流行。
二、手写扩展C库
(1) 准备一个需要转换的C源代码文件,如果没有可以参考以下代码(c源文件名: Conver_Test.c):
void Table99(int n)
{
int i, j;
for(i = 1; i <= n; i++)
{
for(j = 1; j <= n; j++)
{
printf("%d*%d=%-4d", i, j, i*j);
}
printf("\n");
}
}
void Fabocci(void)
{
long int f1, f2;
f1 = f2 = 1;
int i;
for(i = 1; i <= 20; i++)
{
printf("%12ld %12ld", f1, f2);
if(i % 2 == 0)
printf("\n");
f1 = f1 + f2;
f2 = f1 + f2;
}
}
int Max_value(int value1, int value2)
{
if(value1 > value2)
{
return value1;
}
return value2;
}
不知道大家注意到没有, 上述的三个函数分别是“有参数, 没有返回值”, “没有参数, 没有返回值”, “有参数, 有返回值”, 这样就能更清晰的描述该如何把C转换成Python库, 让大家少走弯路.
最后还有一点, 可以发现上述代码没有main( )函数, 所以想测试上述提供的代码, 可在最后添加:
int main(void)
{
int Test = 0;
Table99(9);
Fabocci();
Test = Max_value(9, 4);
printf("Max_value = %d", Test);
}
C源代码测试完毕后, 请务必把main( )函数删除, 以减少后面忘了删除, 导致转换不成功.
(2) 添加导入函数
什么是导入函数?
答:我的理解导入函数就是通过Python函数调用C函数的关键, 他会判断输入是否有误, 然后调用C函数,并返回C函数的返回值.
以下是我为三个C函数写的导入函数:
static PyObject * Conver_Test_Table99(PyObject *self, PyObject *args)
{
int num; //参数
// 判断输入的参数是否为整型, 如果不是返回一个NULL值, i 表示整型, &num为输入参数
if(!(PyArg_ParseTuple(args, "i", &num))){
return NULL;
}
Table99(num); // 执行C函数
return (PyObject *)Py_BuildValue(""); // 把C函数中计算的结果转换成Python对象并返回
}
static PyObject * Conver_Test_Fabocci(PyObject *self, PyObject *args)
{
Fabocci();
return (PyObject *)Py_BuildValue("");
}
static PyObject * Conver_Test_Max_value(PyObject *self, PyObject *args)
{
int num1, num2;
// "ii"表示两个整型参数
if(!(PyArg_ParseTuple(args, "ii", &num1, &num2))){
return NULL;
}
return (PyObject *)Py_BuildValue("i", Max_value(num1, num2));
}
想了解更多关于PyArg_ParseTuple, Py_BuildValue, 请参考以下官方图片:
(3) 添加Python方法
static PyMethodDef Conver_Test_Methods[] = {
{"Table99", Conver_Test_Table99, METH_VARARGS},
{"Fabocci", Conver_Test_Fabocci, METH_VARARGS},
{"Max_value", Conver_Test_Max_value, METH_VARARGS},
{NULL, NULL},
};
(4) 添加模块初始化
void initConver_Test(void)
{
Py_InitModule("Conver_Test", Conver_Test_Methods);
}
添加模块初始化有一点需要注意: 该函数命名格式为init+文件名
至此, 一个手写的C转PYTHON库文件已经写好了, 接下来就剩编译了.
(5) 编译成PYTHON库
编译成C库有两种方法:
① 直接执行命令
命令: gcc -shared -fPIC Conver_Test.c -I/usr/include/python2.7/ -L/usr/lib -lpython2.7 -o Conver_Test.so
注意: 根据python的版本进行相应的更改, 我的python版本为2.7, 如果是其他版本,请注意.
编译完成后, 可在当前目录下查看到相应的Python库文件
② 通过setup库进行编译
- 编写setup.py文件, 请参考以下代码:
#!/usr/bin/env pthon
from distutils.core import setup, Extension
MOD = 'Conver_Test' #库文件名称
example_module = Extension(MOD, sources=['Conver_Test.c'], ) #C文件名称
setup(name=MOD,ext_modules = [example_module],)
- 通过setup.py文件进行编译
命令: python setup.py build
编译完成后, 可在/build/…/…找到相应库文件
(6) 开始运行测试吧
>>> import Conver_Test
>>> Conver_Test.Fabocci()
1 1 2 3
5 8 13 21
34 55 89 144
233 377 610 987
1597 2584 4181 6765
10946 17711 28657 46368
75025 121393 196418 317811
514229 832040 1346269 2178309
3524578 5702887 9227465 14930352
24157817 39088169 63245986 102334155
三、通过swing扩展C库
(1) 安装swig
命令: sudo apt-get install swig
(2) 准备好要转换的C源文件和C头文件, 可参考下面的代码:
/* File:Conver_Testswig.h */
dvoid Table99(int n);
void Fabocci(void);
int Max_value(int value1, int value2);
/* File:Conver_Testswig.c */
#include <stdio.h>
#include "Conver_Testswig.h"
void Table99(int n)
{
int i, j;
for(i = 1; i <= n; i++)
{
for(j = 1; j <= n; j++)
{
printf("%d*%d=%-4d", i, j, i*j);
}
printf("\n");
}
}
void Fabocci(void)
{
long int f1, f2;
f1 = f2 = 1;
int i;
for(i = 1; i <= 20; i++)
{
printf("%12ld %12ld", f1, f2);
if(i % 2 == 0)
printf("\n");
f1 = f1 + f2;
f2 = f1 + f2;
}
}
int Max_value(int value1, int value2)
{
if(value1 > value2)
{
return value1;
}
return value2;
}
(3) 创建一个 .i 文件来配置swig
/* File:Conver_Testswig.i */
%module Conver_Testswig
%{
#define SWIG_FILE_WITH_INIT
#include "Conver_Testswig.h"
%}
void Table99(int n);
void Fabocci(void);
int Max_value(int value1, int value2);
简单介绍:
%module Conver_Testswig 用于配置swig后产生的文件名称
#define SWIG_FILE_WITH_INIT 规定这个C文件将会编译成Python模块
#include "Conver_Testswig.h" 包含头文件
(4) 配置swig
命令: swig -python Conver_Testswig.i
执行该命令会生成一个Conver_Testswig_wrap.c和Conver_Testswig.py文件则代表你配置成功了.
(5) 通过setup库进行编译
① 编写setup.py文件, 请参考以下代码:
#!/usr/bin/env pthon
from distutils.core import setup, Extension
MOD = '_Conver_Testswig'
example_module = Extension(MOD, sources=['Conver_Testswig_wrap.c', 'Conver_Testswig.c'], )
setup(name=MOD,ext_modules = [example_module],)
敲黑板: 请务必注意生成目标文件名称需要加"_"
② 通过setup.py文件进行编译
命令: python setup.py build
编译完成后, 可在/build/…/…找到相应库文件
(6) 开始运行测试吧
>>> import _Conver_Testswig
>>>
>>> _Conver_Testswig.Table99(9)
1*1=1 1*2=2 1*3=3 1*4=4 1*5=5 1*6=6 1*7=7 1*8=8 1*9=9
2*1=2 2*2=4 2*3=6 2*4=8 2*5=10 2*6=12 2*7=14 2*8=16 2*9=18
3*1=3 3*2=6 3*3=9 3*4=12 3*5=15 3*6=18 3*7=21 3*8=24 3*9=27
4*1=4 4*2=8 4*3=12 4*4=16 4*5=20 4*6=24 4*7=28 4*8=32 4*9=36
5*1=5 5*2=10 5*3=15 5*4=20 5*5=25 5*6=30 5*7=35 5*8=40 5*9=45
6*1=6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36 6*7=42 6*8=48 6*9=54
7*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49 7*8=56 7*9=63
8*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64 8*9=72
9*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81
以下隐藏内容为源代码,有需求可以下载,当作是对本站的支持,谢谢。
参考源码下载:https://mp.csdn.net/mp_download/creation/uploadResources/10576662
[erphpdown]解压密码:ZMJPY123[/erphpdown]