首先编写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
但是可以正常使用