python可以利用SO的方式去调用C++中的函数,但是需要一种调试方案来进行python和C++的联合调试,效果是直接在c++代码中打断点,然后python在进行c++so调用的时候,直接进入到断点处:
testlib.cpp
#include <python2.7_d/Python.h> using namespace std; PyObject * CFuncEntry(PyObject * self, PyObject *args) { PyObject * datalist = NULL; PyArg_ParseTuple(args, "O", &datalist); int rst = 0; for(int i=0; i < PyList_Size(datalist); ++i){ int val = PyInt_AsLong(PyList_GetItem(datalist, i)); rst += val; } return Py_BuildValue("i", rst); } PyMODINIT_FUNC initCFuncEntry(void) { static PyMethodDef methods[] = { {"CFuncEntry", (PyCFunction)CFuncEntry, METH_VARARGS, "test lib"}, {NULL, NULL, 0, NULL} }; Py_InitModule("CFuncEntry", methods); }
call_cpp.py
#!/usr/bin/python # -*- encoding utf-8 -*- import CFuncEntry if __name__ == "__main__": numberlist = [1,2,3,4,5,6,7] rst = CFuncEntry.CFuncEntry(numberlist) print rst
setup.py
from distutils.core import setup, Extension module1 = Extension('CFuncEntry', define_macros = [('MAJOR_VERSION', '1'), ('MINOR_VERSION', '0'), ('Py_DEBUG', 1)], include_dirs = ['/usr/local/include'], library_dirs = ['/usr/local/lib'], sources = ['testlib.cpp']) setup (name = 'PackageName', version = '1.0', description = 'This is a demo package', author = 'Martin v. Loewis', author_email = 'martin@v.loewis.de', url = 'https://docs.python.org/extending/building', long_description = ''' This is really just a demo package. ''', ext_modules = [module1])
将setup.py和testlib.cpp放到同一个目录下,执行python setup.py install
可以看到CFuncEntry.so已经生成,这时执行gdb –args python-dbg call_cpp.py可以进入到gdb调试模式:
可能的问题:
1. python-dbg有可能没有安装,需要执行sudo apt-get install python-dbg进行安装;
2. 直接使用g++ -o CFuncEntry.so testlib.cpp -g -shared -fpic -DEBUG -lpython2.7_d 的方式生成的so会出现如下错误:
undefined symbol: Py_InitModule4_64
3. 直接用g++进行编译,生成so,需要加上Py_DEBUG参数:g++ -o CFuncEntry.so testlib.cpp -g -shared -fpic -DEBUG -lpython2.7_d -DPy_DEBUG
参考资料:
1. http://hustoknow.blogspot.com/2013/06/why-your-python-program-cant-start-when.html
2. https://blog.csdn.net/mydear_11000/article/details/52252363