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);
- 定义module名称通常和文件名保持一致。
- %{%}包裹的部分是c语言代码,这段代码会原封不动的复制到mymodule_wrap.c
- 欲导出的函数签名列表。直接从头文件中复制过来即可
$ swig -c++ -python great_module.i
会生成对应的great_module_wrap.c
和great_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
参考
- 知乎作者:Jerry Jho 链接
- SWIG的官方文档SWIG Users Manual
- GCC命令行选项