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/ 感觉文章好,可以小手一抖 -- ...
随机推荐
- iOS 基础 第一天(0804)
OC对象的本质就是一个结构体 为什么说是个结构体? 例如:类里面声明了几个成员变量\实例变量(已添加@plublic),外部对象的指针在访问这个变量的时候是这么写的p->a 0804 注意oc的 ...
- 微软职位内部推荐-Principal Dev Manager for Windows Phone Apps
微软近期Open的职位: Location: China, BeijingDivision: Operations System Group Engineering Group OverviewOSG ...
- net use命令详细解释
1)建立空连接: net use \\IP\ipc$ "" /user:"" (一定要注意:这一行命令中包含了3个空格) 2)建立非空连接: net use \ ...
- python学习笔记29(python中堆的使用)
堆(heap):优先队列的一种,使用优先队列能够以任意顺序增加对象,并且能在任意时间(可能在增加对象的同时)找到(也可能是移除)最小元素,比用于列表中min的方法要高效. Python中并没有独立的堆 ...
- 机器学习基石的泛化理论及VC维部分整理
第四讲 机器学习的可行性 一.Hoeffding's Inequality \(P[\left | \nu -\mu \right |>\epsilon ] \leq 2exp(-2\epsi ...
- bnuoj 20838 Item-Based Recommendation (模拟)
http://www.bnuoj.com/bnuoj/problem_show.php?pid=20838 [题意]: 有点长,略. [code]: #include <iostream> ...
- php+mysql分页类的入门实例
php+mysql分页类的简单代码 时间:2016-02-25 06:16:26来源:网络 导读:php+mysql分页类的简单代码,二个php分页类代码,对商品进行分页展示,当前页面数,每个页面展示 ...
- wordpress换域名后无法登陆的解决方案
第一步:登录到你的数据库管理页面,找到wp_options表: 第二步:将表中的siteurl和home字段的值修改为当前的新域名,siteurl值的修改和home值的修改同理.如下图:
- office2010 office2013打开个别PPT时需要修复的解决方法
写在前面的废话(请直接查看正文部分):一次意外之后,需要重装Microsoft office,于是屁颠屁颠就重装了一次MS office 2013,装好后发现,打开个别ppt/pptx时打不开,提示修 ...
- Akka Stream文档翻译:Motivation
动机 Motivation The way we consume services from the internet today includes many instances of streami ...