Python调用C++方式

方式一(基础篇)

这种方法叫做python的扩展

int great_function(int a) {
    return a + 1;
}

使用python这样调用

>>> from great_module import great_function 
>>> great_function(2)
3
// great_module.c

// 引用python的头文件
#include <Python.h>

int great_function(int a) {
    return a + 1;
}

// 包裹函数,用来包裹需要转化为python的函数,在方法前面加下划线。
static PyObject * _great_function(PyObject *self, PyObject *args)
{
    int _a;
    int res;

    // 检查参数类型是否正确,python参数转化为c
    if (!PyArg_ParseTuple(args, "i", &_a))
        return NULL;
    res = great_function(_a);
    return PyLong_FromLong(res);
}

// 定义的方法表,用于在python中查找
static PyMethodDef GreateModuleMethods[] = {
    {
        "great_function",
        _great_function,
        METH_VARARGS,
        ""
    },
    {NULL, NULL, 0, NULL}
};

// 必须以module名前面加init定义该方法
PyMODINIT_FUNC initgreat_module(void) {
    (void) Py_InitModule("great_module", GreateModuleMethods);
}

在Linux下面,则用gcc编译:

$ gcc -fPIC -shared great_module.c -o great_module.so -I/usr/include/python2.7/ -lpython2.7

gcc命令行参数

  • -shared

    • 生成一个共享对象,可以与其他对象接连成可执行文件
  • -fPIC

    • 适用于动态链接,避免全局偏移表大小的限制,只能在某些机器上运行

在当前目录下得到great_module.so,同理可以在Python中直接使用。

方法二(使用SWIG)

SWIG : Simplified Wrapper and Interface Generator

调用c

不仅可以用于python,也可以用于其他java/perl/ruby/php/JavaScript/Go。

/* great_module.i */
%module great_module
%{
int great_function(int a) {
    return a + 1;
}
%}
int great_function(int a);
  1. 定义module名称通常和文件名保持一致。
  2. %{%}包裹的部分是c语言代码,这段代码会原封不动的复制到mymodule_wrap.c
  3. 欲导出的函数签名列表。直接从头文件中复制过来即可
$ swig -c++ -python great_module.i

会生成对应的great_module_wrap.cgreat_module.py文件

再执行:

$ g++ -fPIC -shared great_class_wrap.cxx -o _great_class.so  -I/usr/include/python2.7/ -lpython2.7

生成对应的_great_module.so文件,这时,我们就可以再python中直接调用了

from great_module import great_function

print great_function(9)

>>> 10

调用c++

定义一个头文件,great_class.h

#ifndef GREAT_CLASS
#define GREAT_CLASS
class Great {
    private:
        int s;

    public:
        void setWall (int _s) {s = _s;};
        int getWall() {return s;};
};
#endif

再定义一个great_class.i的swig配置文件,这里不用再写一遍SWIG的定义了,直接使用SWIG的%include指令;
在SWIG编译时要加-c++这个选项,生成的扩展名为cxx

/* great_class.h */

%module great_class
%{
#include "great_class.h"
%}
%include "great_class.h"

执行命令:

$ swig -c++ -python great_class.i

在Linux下,使用C++编译器g++

g++ -fPIC -shared great_class_wrap.cxx -o _great_class.so  -I/usr/include/python2.7/ -lpython2.7

生成对应的_great_class.so文件。现在可以直接在python中输入

import great_class
c = great_class.Great()
c.setWall(10)
print c.getWall()

>>> 10

参考


NickZhou
1 声望1 粉丝

Android开发工程师 ~ 准备转型~(≧▽≦)/~啦啦啦