织梦CMS - 轻松建站从此开始!

罗索

python的C、c++扩展

jackyhwei 发布于 2011-10-16 13:01 点击:次 
python的强大不仅表现在其功能上,而且还表现在其扩展能力上。使用C/C++很容易编写python的模块,扩展python的功能。同时将性能要求比较高的代码使用C/C++编写,能更好的弥补脚本语言执行速度慢的缺陷。
TAG:

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.

(andyhuiruan)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201110/15138.html]
本文出处:blog.chinaunix.net 作者:andyhuiruan
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容