python扩展实现方法--python与c混和编程
前言(更新:更方便易用的方式在http://www.swig.org/tutorial.html)
需要扩展Python语言的理由:
创建Python扩展的步骤
1. 创建应用程序代码
#include <stdlib.h>
#include <string.h>
#define BUFSIZE 10
int fac(int n) {
if (n < 2)
return 1;
return n * fac(n - 1);
}
char *reverse(char *s) {
register char t;
char *p = s;
char *q = (s + (strlen(s) - 1));
while (p < q) {
t = *p;
*p++ = *q;
*q-- = t;
}
return s;
}
int main() {
char s[BUFSIZE];
printf("4! == %d\n", fac(4));
printf("8! == %d\n", fac(8));
printf("12! == %d\n", fac(12));
strcpy(s, "abcdef");
printf("reversing 'abcdef', we get '%s'\n", reverse(s));
strcpy(s, "madam");
printf("reversing 'madam', we get '%s'\n", reverse(s));
return 0;
}

2. 利用样板来包装代码
a. 包含python的头文件
b. 为每个模块的每一个函数增加一个型如PyObject* Module_func()的包装函数
int res;//计算结果值
int num;//参数
PyObject* retval;//返回值
//i表示需要传递进来的参数类型为整型,如果是,就赋值给num,如果不是,返回NULL;
res = PyArg_ParseTuple(args, "i", &num);
if (!res) {
//包装函数返回NULL,就会在Python调用中产生一个TypeError的异常
return NULL;
}
res = fac(num);
//需要把c中计算的结果转成python对象,i代表整数对象类型。
retval = (PyObject *)Py_BuildValue("i", res);
return retval;
}
int m;
if (!(PyArg_ParseTuple(args, "i", &num))) {
return NULL;
}
return (PyObject *)Py_BuildValue("i", fac(num));
}

Extest_reverse(PyObject *self, PyObject *args) {
char *orignal;
if (!(PyArg_ParseTuple(args, "s", &orignal))) {
return NULL;
}
return (PyObject *)Py_BuildValue("s", reverse(orignal));
}
Extest_doppel(PyObject *self, PyObject *args) {
char *orignal;
if (!(PyArg_ParseTuple(args, "s", &orignal))) {
return NULL;
}
//ss,就可以返回两个字符串,应该reverse是在原字符串上进行操作,所以需要先strdup复制一下
return (PyObject *)Py_BuildValue("ss", orignal, reverse(strdup(orignal)));
}
Extest_doppel(PyObject *self, PyObject *args) {
char *orignal;
char *reversed;
PyObject * retval;
if (!(PyArg_ParseTuple(args, "s", &orignal))) {
return NULL;
}
retval = (PyObject *)Py_BuildValue("ss", orignal, reversed=reverse(strdup(orignal)));
free(reversed);
return retval;
}
c. 为每个模块增加一个型如PyMethodDef ModuleMethods[]的数组
ExtestMethods[] = {
{"fac", Extest_fac, METH_VARARGS},
{"doppel", Extest_doppel, METH_VARARGS},
{"reverse", Extest_reverse, METH_VARARGS},
{NULL, NULL},
};
d. 增加模块初始化函数void initMethod()
Py_InitModule("Extest", ExtestMethods);
}
#include <stdlib.h>
#include <string.h>
#include "Python.h"
#define BUFSIZE 10
int fac(int n) {
if (n < 2)
return 1;
return n * fac(n - 1);
}
char *reverse(char *s) {
register char t;
char *p = s;
char *q = (s + (strlen(s) - 1));
while (p < q) {
t = *p;
*p++ = *q;
*q-- = t;
}
return s;
}
static PyObject *
Extest_fac(PyObject *self, PyObject *args) {
int res;
int num;
PyObject* retval;
res = PyArg_ParseTuple(args, "i", &num);
if (!res) {
return NULL;
}
res = fac(num);
retval = (PyObject *)Py_BuildValue("i", res);
return retval;
}
static PyObject *
Extest_reverse(PyObject *self, PyObject *args) {
char *orignal;
if (!(PyArg_ParseTuple(args, "s", &orignal))) {
return NULL;
}
return (PyObject *)Py_BuildValue("s", reverse(orignal));
}
static PyObject *
Extest_doppel(PyObject *self, PyObject *args) {
char *orignal;
char *resv;
PyObject *retval;
if (!(PyArg_ParseTuple(args, "s", &orignal))) {
return NULL;
}
retval = (PyObject *)Py_BuildValue("ss", orignal, resv=reverse(strdup(orignal)));
free(resv);
return retval;
}
static PyMethodDef
ExtestMethods[] = {
{"fac", Extest_fac, METH_VARARGS},
{"doppel", Extest_doppel, METH_VARARGS},
{"reverse", Extest_reverse, METH_VARARGS},
{NULL, NULL},
};
void initExtest() {
Py_InitModule("Extest", ExtestMethods);
}
int main() {
char s[BUFSIZE];
printf("4! == %d\n", fac(4));
printf("8! == %d\n", fac(8));
printf("12! == %d\n", fac(12));
strcpy(s, "abcdef");
printf("reversing 'abcdef', we get '%s'\n", reverse(s));
strcpy(s, "madam");
printf("reversing 'madam', we get '%s'\n", reverse(s));
test();
return 0;
}
3. 编译与测试
a. 创建setup.py
from distutils.core import setup, Extension
MOD = 'Extest'
setup(name=MOD, ext_modules=[Extension(MOD, sources=['Extest.c'])])
b. 通过运行setup.py来编译和连接你的代码




c. 进行调试
from ctypes import *
import os
#需要使用绝对路径
extest = cdll.LoadLibrary(os.getcwd() + '/Extest.so')
print extest.fac(4)


Extest_test(PyObject *self, PyObject *args) {
test();
#返回空的话,就使用下面这一句
return (PyObject *)Py_BuildValue("");
}
简单性能比较
import time
start = time.time()
a = Extest.reverse("abcd")
timeC = time.time() - start
print 'C costs', timeC, 'the result is', a
start = time.time()
b = list("abcd")
b.reverse()
b = ''.join(b)
timePython = time.time()-start
print 'Python costs', timePython, 'the result is', b

python扩展实现方法--python与c混和编程的更多相关文章
- python扩展实现方法--python与c混和编程 转自:http://www.cnblogs.com/btchenguang/archive/2012/09/04/2670849.html
前言 需要扩展Python语言的理由: 创建Python扩展的步骤 1. 创建应用程序代码 2. 利用样板来包装代码 a. 包含python的头文件 b. 为每个模块的每一个函数增加一个型如PyObj ...
- Python List extend()方法
Python List extend()方法 Python 列表 描述 extend() 函数用于在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表). 语法 extend()方法语法 ...
- Python os.getcwd() 方法
Python os.getcwd() 方法 Python OS 文件/目录方法 概述 os.getcwd() 方法用于返回当前工作目录. 语法 getcwd()方法语法格式如下: os.getcwd ...
- Python和C扩展实现方法
一.Python和C扩展 cPython是C编写的,python的扩展可以用C来写,也便于移植到C++. 编写的Python扩展,需要编译成一个.so的共享库. Python程序中. 官方文档:htt ...
- Python扩展方法一二事
前言 跟着一个有强迫症的老板干活是一件极其幸福的事情(你懂的).最近碰到一个问题,简单的说就是对一个对象做出部分修改后仍然返回此对象,于是我就写了一个方法,老板看了之后只有一句话:不雅观,改成直接对此 ...
- Python扩展之类的魔术方法
Python中类的魔术方法 在Python中以两个下划线开头的方法,__init__.__str__.__doc__.__new__等,被称为"魔术方法"(Magic method ...
- 《扩展和嵌入python解释器》1.4 模块方法表和初始化函数
<扩展和嵌入python解释器>1.4 模块方法表和初始化函数 1.4 模块方法表和初始化函数 下面,我演示如何从Python程序调用spam_system().首先,我们需要在’方法 ...
- Python 扩展技术总结(转)
一般来说,所有能被整合或导入到其他Python脚本中的代码,都可以称为扩展.你可以用纯Python来写扩展,也可以用C/C++之类的编译型语言来写扩展,甚至可以用java,C都可以来写 python扩 ...
- Python基础+Pythonweb+Python扩展+Python选修四大专题 超强麦子学院Python35G视频教程
[保持在百度网盘中的, 可以在观看,嘿嘿 内容有点多,要想下载, 回复后就可以查看下载地址,资源收集不易,请好好珍惜] 下载地址:http://www.fu83.cc/ 感觉文章好,可以小手一抖 -- ...
随机推荐
- C语言socket编程--每日签到
前几天写了个python的每日签到,你运行还得借助crontab,很是不爽.....正好前几天看了个关于c编写daemon进程,加上自己那点可怜的socket知识,于是我们重操旧页,C语言版的每日签到 ...
- wpf datagrid 行双击事件
Xaml: <DataGrid ItemsSource="{Binding SessionList}" Grid.Row="2" Grid.Column= ...
- Hello World for U (20)
Given any string of N (>=5) characters, you are asked to form the characters into the shape of U. ...
- 【CSLA】Component-based,Scalable,LogicalArchitecture
我能说我没看懂吗 ? http://www.cnblogs.com/lonely7345/archive/2010/02/06/1665171.html
- 编译升级php
http://www.linux-centos.com/2014/11/16/%E7%BC%96%E8%AF%91%E5%8D%87%E7%BA%A7%E4%BB%8Ephp5-2-17%E5%88% ...
- 微软职位内部推荐-Principal Dev Manager for Windows Phone Apps
微软近期Open的职位: Location: China, BeijingDivision: Operations System Group Engineering Group OverviewOSG ...
- drag drop小游戏
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- 对.net orm工具Dapper在多数据库方面的优化
Dapper是近2年异军突起的新ORM工具,它有ado.net般的高性能又有反射映射实体的灵活性,非常适合喜欢原生sql的程序员使用,而且它源码很小,十分轻便.我写本博客的目的不是为了介绍Dapper ...
- asp网站通用后台代码设计
main2.css: a:link {color: #333333; text-decoration: none}a:visited {color: #000000; text-decoration: ...
- uva 11069
一开始打了个表 发现 a[i] = a[i-3]+a[i-2]; #include <iostream> #include <fstream> #include <cs ...