首先編寫LGadd_model.cpp
#define PY_SSIZE_T_CLEAN
#include "Python.h"
/*由於 Python 可能會定義一些能在某些系統上影響標準頭文件的預處理器定義,
因此在包含任何標準頭文件之前,你 必須 先包含 Python.h。
推薦總是在 Python.h 前定義 PY_SSIZE_T_CLEAN 。查看 提取擴展函數的參數 來了解這個宏的更多內容
https://docs.python.org/zh-cn/3.7/extending/extending.html#parsetuple
*/
// c++ 實現加法,傳入倆個int型,輸出和.
int add(int a, int b){
return a+b;
};
/*模塊中每個可供Python調用的函數都需要一個對應的包裹函數*/
static PyObject *LG_add(PyObject * self, PyObject *args){
/*self參數指向模塊對象對於對象實例則指向方法。
args參數是指向一個Python的tuple對象的指針,其中包含參數,
每個tuple項對應一個調用參數。 這些參數也全都是Python對象,
在C函數中使用它們需要先將其轉換爲C值*/
int a,b;
/*Python API 中的函數PyArg_ParseTuple()會檢查參數類型並將其轉換爲C值,
這裏 'ii' 表示倆個整型*/
if (!PyArg_ParseTuple(args,"ii",&a,&b)) {
return NULL;
}
return (PyObject*)Py_BuildValue("i",add(a,b));
/* 這裏返回的值,必須這麼寫,返回的是一個python對象,而不能直接是C對象.*/
};
// 定義一個方法表,方法表中可以包含多個方法
static PyMethodDef LGMethods[] = {
/* "add" 最終在python中模塊調用的方法名,
LG_add, 這是對應的C++ 程序的方法名,
也就是python中 使用 模塊.add 調用 C++ 中的LG_add函數*/
{"add", LG_add, METH_VARARGS},
{NULL, NULL} /* Sentinel */
};
// 定義模塊結構 引用方法表
static struct PyModuleDef LGmodule = {
PyModuleDef_HEAD_INIT,
"LG", /* 模塊的名字 */
NULL, /* module documentation, may be NULL */
-1, /* size of per-interpreter state of the module,
or -1 if the module keeps state in global variables. */
LGMethods /*模塊方法表*/
};
/*模塊初始化函數必須命名爲PyInit_name(),其中name是模塊的名字,並應該定義爲非static.
模塊結構必須傳遞給解釋器的模塊初始化函數*/
PyMODINIT_FUNC
PyInit_LG(void){
return PyModule_Create(&LGmodule);
}
/*需要特別注意 文件各方法名稱的對應關係,必須完全對應*/
編寫 setup.py文件
from distutils.core import setup,Extension
MOD = 'LG' # 模塊名
setup(name=MOD,ext_modules=[Extension(MOD,sources=['LGadd_model.cpp'])])
運行進行編譯
python setup.py build
輸出:
running build
running build_ext
building 'LG' extension
gcc -pthread -B /home/XXX/anaconda3/compiler_compat -Wl,--sysroot=/ -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -I/home/XXX/anaconda3/include/python3.7m -c cal_ids.cpp -o build/temp.linux-x86_64-3.7/cal_ids.o
cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not for C++
creating build/lib.linux-x86_64-3.7
g++ -pthread -shared -B /home/XXX/anaconda3/compiler_compat -L/home/XXX/anaconda3/lib -Wl,-rpath=/home/XXX/anaconda3/lib -Wl,--no-as-needed -Wl,--sysroot=/ build/temp.linux-x86_64-3.7/cal_ids.o -o build/lib.linux-x86_64-3.7/LG.cpython-37m-x86_64-linux-gnu.so
運行進行安裝
python setup.py install
輸出:
running install
running bdist_egg
running egg_info
creating LG.egg-info
writing LG.egg-info/PKG-INFO
writing dependency_links to LG.egg-info/dependency_links.txt
writing top-level names to LG.egg-info/top_level.txt
writing manifest file 'LG.egg-info/SOURCES.txt'
reading manifest file 'LG.egg-info/SOURCES.txt'
writing manifest file 'LG.egg-info/SOURCES.txt'
installing library code to build/bdist.linux-x86_64/egg
running install_lib
running build_ext
creating build/bdist.linux-x86_64
creating build/bdist.linux-x86_64/egg
copying build/lib.linux-x86_64-3.7/LG.cpython-37m-x86_64-linux-gnu.so -> build/bdist.linux-x86_64/egg
creating stub loader for LG.cpython-37m-x86_64-linux-gnu.so
byte-compiling build/bdist.linux-x86_64/egg/LG.py to LG.cpython-37.pyc
creating build/bdist.linux-x86_64/egg/EGG-INFO
copying LG.egg-info/PKG-INFO -> build/bdist.linux-x86_64/egg/EGG-INFO
copying LG.egg-info/SOURCES.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
copying LG.egg-info/dependency_links.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
copying LG.egg-info/top_level.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
writing build/bdist.linux-x86_64/egg/EGG-INFO/native_libs.txt
zip_safe flag not set; analyzing archive contents...
__pycache__.LG.cpython-37: module references __file__
creating dist
creating 'dist/LG-0.0.0-py3.7-linux-x86_64.egg' and adding 'build/bdist.linux-x86_64/egg' to it
removing 'build/bdist.linux-x86_64/egg' (and everything under it)
Processing LG-0.0.0-py3.7-linux-x86_64.egg
creating /home/XXX/anaconda3/lib/python3.7/site-packages/LG-0.0.0-py3.7-linux-x86_64.egg
Extracting LG-0.0.0-py3.7-linux-x86_64.egg to /home/XXX/anaconda3/lib/python3.7/site-packages
Adding LG 0.0.0 to easy-install.pth file
Installed /home/XXX/anaconda3/lib/python3.7/site-packages/LG-0.0.0-py3.7-linux-x86_64.egg
Processing dependencies for LG==0.0.0
Finished processing dependencies for LG==0.0.0
最終在python文件中就可以調用
import LG
a = 1
b =2
print(LG.add(a,b))
在調用時, 雖然LG模塊 顯示No module named LG
但是可以正常使用