python和C++联合调试

    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 = '[email protected]',                                                                                                                          
       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

image

可以看到CFuncEntry.so已经生成,这时执行gdb –args python-dbg call_cpp.py可以进入到gdb调试模式:

image

image

可能的问题:

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

clipboard

参考资料:

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 

猜你喜欢

转载自www.cnblogs.com/justinzhang/p/9282334.html