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命令列選項