神奇的python(三)之Python扩展C/C++库(C转换为Python)

一、 简介

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]

  • 7
    点赞
  • 58
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值