本次调试的是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
C
// fputsmodule.c
#define PY_SSIZE_T_CLEAN
#include
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下推荐使用MSVC编译(这里使用的最新版本,对应python3.7),可以在虚拟环境下运行python命令查看当前Python版本对应的MSVC版本
版本不对应可能会提醒 “Unable to find vcvarsall.bat” 错误 |
安装:
模块安装: 激活Python虚拟环境并cd到setup.py所在文件夹执行
python setup.py install --user
下面就是正常的调试试,到达断点时可进入到C源代码调试
sudo apt-get install gcc
sudo apt-get install gdb
如果出现***.so.** is not a symbolic link# 例如报错:
/usr/lib/wsl/lib/libcuda.so.1 is not a symbolic link
# 则先执行:
sudo ln -sf /usr/lib/wsl/lib/libcuda.so.1
# 再重新执行之前的命令
和Windows调试基本一致
之后就更该图中的两个地方,即指定当前虚拟环境的python和gdb的二进制文件路径,若不指定会报错,python二进制文件必须为当前虚拟环境的Python路径,否则即使不会报错,也不会进入到C断点当中
步骤
生成拓展:
python setup.py install --user
注意生成前,将setup.py中标注的两个参数注释掉
启动Python调试,和Windows下一样
附加C拓展调试
其他和windows下调试步骤一致
以上就是关于Python和C++联合调试的详细步骤,有些细节可能未涉及到,欢迎留言,我会及时补充
下一篇章记录Windows的Linux子系统wsl2下使用GPU跑深度学习模型,有需要的同学欢迎留言