python和c++分别在Linux和Windows下联合调试
本次调试的是Python调用通过以下命令命令编译生成的模块,**
python setup.py xx
# 例如
python setup.py build_ext
python setup.py install
Windows上是*.pyd, Linux上是*.so,是动态链接库文件, 下面介绍从编译到调试的详细过程, 使用工具:Visual Studio Code,测试代码及相关工具地址:https://github.com/ipyffor/DebugMixedPythonAndC
参考:https://zhuanlan.zhihu.com/p/107685869
首先创建一个python测试项目和一个c++拓展项目
-
C
// fputsmodule.c #define PY_SSIZE_T_CLEAN #include <Python.h> static PyObject *StringTooShortError = NULL; static PyObject *method_fputs(PyObject *self, PyObject *args, PyObject *kw) { char *str, *filename = NULL; int bytes_copied = -1; /* Parse arguments */ char *kwlist[] = {"content", "filename", NULL}; if(!PyArg_ParseTupleAndKeywords(args, kw, "ss", kwlist, &str, &filename)) { return NULL; } if (strlen(str) < 10) { /* Passing custom exception */ PyErr_SetString(StringTooShortError, "String length must be greater than 10"); return NULL; } FILE *fp = fopen(filename, "w"); bytes_copied = fputs(str, fp); fclose(fp); return (PyObject *)Py_BuildValue("i", bytes_copied); } static PyMethodDef FputsMethods[] = { {"fputs", method_fputs, METH_VARARGS | METH_KEYWORDS, "Python interface for fputs C library function"}, {NULL, NULL, 0, NULL} }; static struct PyModuleDef fputsmodule = { PyModuleDef_HEAD_INIT, "fputs", "Python interface for the fputs C library function", -1, FputsMethods }; PyMODINIT_FUNC PyInit_fputs(void) { /* Assign module value */ PyObject *module = PyModule_Create(&fputsmodule); /* Initialize new exception object */ StringTooShortError = PyErr_NewException("fputs.StringTooShortError", NULL, NULL); /* Add exception object to your module */ PyModule_AddObject(module, "StringTooShortError", StringTooShortError); return module; }
# setup.py # 模块安装脚本 from distutils.core import setup, Extension def main(): setup( name="fputs", version="1.0.0", description="Python interface for the fputs C library function", author="hanbing", author_email="[email protected]", ext_modules=[Extension( "fputs", ["fputsmodule.c"], language="c++", # Linux下注释这两个参数 extra_compile_args=['/Zi'], extra_link_args=['/DEBUG'] )], ) if __name__ == "__main__": main()
-
Python:
# fputs_test.py import os # 打印当前进程id print("pid:",os.getpid()) # 调用模块 import fputs fputs.fputs("hello world! You are good!", "hello.txt") print("hello world!")
一、在Windows下进行调试
1. 编译器安装
Windows下推荐使用MSVC编译(这里使用的最新版本,对应python3.7),可以在虚拟环境下运行python命令查看当前Python版本对应的MSVC版本
版本不对应可能会提醒 “Unable to find vcvarsall.bat” 错误 |
安装:
-
运行项目文件夹tools下的vs_buildtools__1879205487.1594739136.exe
-
如图
2. C拓展模块安装
模块安装: 激活Python虚拟环境并cd到setup.py所在文件夹执行python setup.py install --user
3. 调试
3.1 vscode调试配置
-
添加Python当前文件调试配置(该调试会启动当前打开的Python脚本)
-
添加C拓展调试配置
3.2 调试
-
给Python脚本下好断点,启动调试
-
对C模块附加到Python进程中进行调试
下面就是正常的调试试,到达断点时可进入到C源代码调试
二、在Linux下进行调试
环境
1. Python环境(3.7)
2. C/C++环境
- 安装GCC和GDB
sudo apt-get install gcc sudo apt-get install gdb
可以进行如下操作:# 例如报错: /usr/lib/wsl/lib/libcuda.so.1 is not a symbolic link # 则先执行: sudo ln -sf /usr/lib/wsl/lib/libcuda.so.1 # 再重新执行之前的命令
3. 调试
和Windows调试基本一致
需要更改拓展的附加调试配置,如图:
之后就更该图中的两个地方,即指定当前虚拟环境的python和gdb的二进制文件路径,若不指定会报错,python二进制文件必须为当前虚拟环境的Python路径,否则即使不会报错,也不会进入到C断点当中
步骤
-
生成拓展:
python setup.py install --user
注意生成前,将setup.py中标注的两个参数注释掉
-
启动Python调试,和Windows下一样
-
附加C拓展调试
其他和windows下调试步骤一致
以上就是关于Python和C++联合调试的详细步骤,有些细节可能未涉及到,欢迎留言,我会及时补充
标签:Python,setup,C++,python,fputs,NULL,调试 From: https://www.cnblogs.com/lidabo/p/17076849.html