本次调试的是Python调用通过以下命令命令编译生成的模块,**
python setup.py xx
# 例如
python setup.py build_ext
python setup.py install
- 1
- 2
- 3
- 4
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; }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
# 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="beatmight@gmail.com", ext_modules=[Extension( "fputs", ["fputsmodule.c"], language="c++", # Linux下注释这两个参数 extra_compile_args=['/Zi'], extra_link_args=['/DEBUG'] )], ) if __name__ == "__main__": main()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
-
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!")
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
一、在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
- 1
- 2
可以进行如下操作:# 例如报错: /usr/lib/wsl/lib/libcuda.so.1 is not a symbolic link # 则先执行: sudo ln -sf /usr/lib/wsl/lib/libcuda.so.1 # 再重新执行之前的命令
- 1
- 2
- 3
- 4
- 5
3. 调试
和Windows调试基本一致
需要更改拓展的附加调试配置,如图:
之后就更该图中的两个地方,即指定当前虚拟环境的python和gdb的二进制文件路径,若不指定会报错,python二进制文件必须为当前虚拟环境的Python路径,否则即使不会报错,也不会进入到C断点当中
步骤
-
生成拓展:
python setup.py install --user
注意生成前,将setup.py中标注的两个参数注释掉
-
启动Python调试,和Windows下一样
-
附加C拓展调试
其他和windows下调试步骤一致
以上就是关于Python和C++联合调试的详细步骤,有些细节可能未涉及到,欢迎留言,我会及时补充😁
下一篇章记录Windows的Linux子系统wsl2下使用GPU跑深度学习模型,有需要的同学欢迎留言
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
2022-01-29 使用gprof2dot和graphivz生成程序运行调用图
2022-01-29 绘制函数调用图(call graph):doxygen + graphviz
2021-01-29 C++得到当前进程所占用的内存
2021-01-29 32位Exe程序突破系统内存限制
2021-01-29 zookeeper 的介绍以及使用
2019-01-29 Linux中的configure,make,make install到底在做些什么
2019-01-29 cmake中添加-fPIC编译选项方法