注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

liangxh2008的博客

 
 
 

日志

 
 

python的C、c++扩展  

2010-07-29 14:51:13|  分类: python |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

http://blog.chinaunix.net/u3/110228/showart.php?id=2148725


python的强大不仅表现在其功能上,而且还表现在其扩展能力上。
使用C/C++很容易编写python的模块,扩展python的功能。
同时将性能要求比较高的代码使用C/C++编写,能更好的弥补
脚本语言执行速度慢的缺陷。

 

1. python的C语言扩展

1.1 TestCLib.c: 提供python的模块接口
#include "Python.h"
#include <stdlib.h>
#include <stdio.h>

long fac(long);

// ------------------------------------------------------
// Make C code usable in Python
// ------------------------------------------------------
PyObject*   TestCLib_fac(PyObject * self, PyObject *args)
{
    long num;

    if ( ! PyArg_ParseTuple(args,"l",&num)){
        return NULL;
    }
    return (PyObject*)Py_BuildValue("l",fac(num));
}
static PyMethodDef  TestCLibMethods[] = {
    {"fac",TestCLib_fac,METH_VARARGS},
    {NULL,NULL}
};
void initTestCLib()
{
    Py_InitModule("TestCLib",TestCLibMethods);
}


1.2 test.c: 具体的C语言实现

#include <stdlib.h>
#include <stdio.h>

// ------------------------------------------------------
// Pure C code
// ------------------------------------------------------

long fac(long n)
{
    if ( n < 0){
        return fac(-n);
    } else if ( n < 2 ){
        return 1;
    } else {
        return n * fac(n-1);
    }
}

1.3 test.py: 测试脚本
#!/usr/bin/env python

import TestCLib as TestLib

for i in range(10,20) :
    f1 = TestLib.fac(i)
    print "%d! = %d"%(i,f1)

1.4 编译与运行
编译命令:
gcc -fPIC -shared  -o TestCLib.so TestCLib.c test.c -I /usr/local/python/include/python2.6/
将生成的动态链接库 TestCLib.so 和 test.py 放在同一个目录下

运行命令:
python test.py

2. python 的C++扩展
2.1 test.h 类的定义
#ifndef _TEST_H_
#define _TEST_H_

namespace Test{
    class CTest{
        public:
            long fac(long);
    };
}

#endi

2.2 test.cpp 类的实现
#include <cstdlib>
#include <cstdio>
#include "test.h"

// ------------------------------------------------------
// Pure CPP code
// ------------------------------------------------------

namespace Test{
    long CTest::fac(long n)
    {
        if ( n < 0){
            return fac(-n);
        } else if ( n < 2 ){
            return 1;
        } else {
            return n * fac(n-1);
        }
    }
}

2.3 TestCPPLib.cpp: python的模块接口
#include "Python.h"
#include "test.h"

// ------------------------------------------------------
// Make CPP code usable in Python
// ------------------------------------------------------
PyObject*   TestCPPLib_fac(PyObject * self, PyObject *args)
{
    Test::CTest test;
    long num;

    if ( ! PyArg_ParseTuple(args,"l",&num)){
        return NULL;
    }
    return (PyObject*)Py_BuildValue("l",test.fac(num));
}
static PyMethodDef  TestCPPLibMethods[] = {
    {"fac",TestCPPLib_fac,METH_VARARGS},
    {NULL,NULL}
};
extern "C" void initTestCPPLib()
{
    Py_InitModule("TestCPPLib",TestCPPLibMethods);
}

2.4 test.py: 测试脚本
#!/usr/bin/env python

import TestCPPLib as TestLib

for i in range(10,20) :
    f1 = TestLib.fac(i)
    print "%d! = %d"%(i,f1)

2.5 编译运行
编译命令:
g++ -fPIC -shared -o TestCPPLib.so TestCPPLib.cpp test.cpp -I /usr/local/python/include/python2.6/
将TestCPPLib.so 和 test.py 放在同一个目录下

运行命令:
python test.py

2.6 注意:
在c++的python模块接口中:初始化函数init需要使用extern "C"声明。
如果上述 initTestCPPLib() 直接定义为:
void initTestCPPLib()
{
    Py_InitModule("TestCPPLib",TestCPPLibMethods);
}
则在运行test.py时,会提示错误:
dynamic module does not define init function

原因是由于g++在编译时改变了函数名,
而python按照名字查找模块初始化函数,自然会找不到了。

 

3. 总结
python的导出函数的原型是:
PyObject* fun(PyObject * self, PyObject* args);

同时对于模块mo,需要编写初始化函数initmo.

  评论这张
 
阅读(1542)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017