KBEngine(CBE)引擎研究 (二) C++ Python 混合调试

C++、Python混合调试基础

混合调试,可以在C++和Python代码中切换,有详细的调用栈信息。非常方便。
link:C++ Python混合调试
link:Python混合开发

CBE混合调试QA

Q:为什么CBE本身不支持混合调试?
A:CBE直接采用了python源码,编译成静态库,最终编译到具体的exe中。所调用的脚本直接就被解释到了内存中的代码段,然后拿到函数指针直接调用,所以无法调试到具体的python代码。

Q:那要怎么改?
A:改成不使用源码的形势。也就是安装python,直接包含头文件,加载lib库的方式调用。

Q:源码编译和普通调用优缺点?
A:源码编译不依赖生产环境(也就是不需要生产环境安装对应的python),但调试困难。
普通的调用方式支持混合调试。但生产环境需要安装python

对于实际工程来说。编译机可以采用CBE源码编译。开发机可以自行配置混合调试环境。

CBE开启混合调试步骤

环境

系统:Win10
IDE:VS2017
工程版本:Python3.7.2(安装版本),KBEngine2.3.5

以我安装的路径为例 C:\Python37-32

CBE中的项目依赖图

项目中直接采用的python源码,总共编译了9个项目,静态编译
在这里插入图片描述
生成项目依赖图:

VS Enterprise版本
在<体系结构>中可以直接生成

其他版本:
在kbengine-2.3.5\kbe\src目录下,搜索*. vcxproj文件,依次搜索项目对应的字符串“_ctypes.vcxproj _elementtree.vcxproj _hashlib.vcxproj _socket.vcxproj _ssl.vcxproj pyexpat.vcxproj select.vcxproj unicodedata.vcxproj pythoncore.vcxproj”
在*.vcxproj文件中'ProjectReference'字段就是依赖项。
依赖图如下:
在这里插入图片描述

修改CBE中Python的调用方式

根据依赖图很容易发现,pyscript项目对python本身进行了一次封装。这是我们的中修改对象。

  1. 安装支持混合调试的Python
    link: python

  2. VS需要安装Python调试环境
    link:C++ Python混合调试

  3. 删掉CBE解决方案中的python项目
    在这里插入图片描述
    删掉kbengine-2.3.5\kbe\src\lib下的python文件夹(可以不删,但后续操作时需要自己区分好)

  4. 删除项目中对于原python路径的头文件依赖(可以自行在VS项目属性中修改,下同)
    搜索*. vcxproj 包含有’python/PC’,总共76项
    把’*python/PC;*python/Include;’替换成’ C:/Python37-32/include;’

  5. 删除对原Python的静态库依赖
    搜索*. vcxproj 包含有’ _ctypes.pyd _elementtree. pyd _hashlib. pyd _socket. pyd _ssl. pyd pyexpat. pyd select. pyd unicodedata. pyd python34.lib python34.lib’以及他们的_d版本,例如‘_ctypes_d.pyd’
    并在该工程的链接库目录中添加’ C:\Python37-32\libs’。根据依赖图可以确定涉及工程:
    在这里插入图片描述

  6. 尝试编译下,并解决编译错误
    Error: PyUnicode_AsUTF8AndSize 无法从“const char *”转换为“char *”
    Fix: 修改PyUnicode_AsUTF8AndSize函数, python\include\unicodeobject.h
    对于C++来说,返回值并不影响函数的符号名,这里的风险就是调用了这个函数的指针,修改了Python不希望你修改的地方。我个人觉得这里没什么问题。你也可以不修改Python源码,而是修改工程中对这个函数的所有调用。
    Error: 涉及getbuildinfo.c
    Fix: 这个文件是python源码中的,原先工程为了编译过,给很多项目中添加了个这个文件。可以挨个项目查找直接删除或者*.filters 以及 *.vcxproj搜索删除
    Error:无法解析的外部符号 __Py_RefTotal
    Fix: 这个是因为pyscript项目预编译包含Py_NO_ENABLE_SHARED,也就是非动态库宏。
    而实际上这种直接调用python的方式是采用动态库的,搜索*.vcxproj 包含’‘Py_NO_ENABLE_SHARED’,并全部删掉
    Error:有些工程无法读取python37_d.lib
    Fix: 在工程配置中添加路径C:\Python37-32\libs
    Error:LNK2001: 无法解析的外部符号 _PyInit__socket
    Fix: 这个文件在pyscript工程中的install_py_dlls文件,这里是动态加载python库。而直接调用python自动包含这一步了。Install_py_dlls.h install_py_dlls.cpp可以直接删掉或者注释相关代码
    Error: Cellapp工程error LNK2019: 无法解析的外部符号 _uncompress
    Fix: Cellapp项目添加对应的zip.lib,debug下是zip_b.lib

  7. 到这里就整体编译通过了

  8. 拷贝C:\Python37-32\Lib,C:\Python37-32\DLLs到kbengine-2.3.5\kbe\res\scripts\common
    覆盖掉以前common下的lib文件夹

  9. 启动进城后还会发现一些报错
    30 50 100,这个是demo中的一些配置错了。
    修改demon路径下的NPCObject.def即可,改为’30,50,100’。
    类似错误都是配置格式修改过,demo不匹配导致的,自行修改就好。

启动项目看看

修改demo中的startserver.bat,注释掉loginApp,然后启动bat
在VS中启动loginAPP,设置启动项为python本地调试
在VS中启动需要的demo进程

在函数initializeEnd()中的调用部分PyObject* pyResult打上断点。
结果图如下:
在这里插入图片描述
在这里插入图片描述

我们发现正确的跳转到Python中了,运行栈也很清晰。
当然我们还可以继续优化,直接调试python源码,下载对应版本的源码,当调试时提示没有源文件时,设置只想源码目录即可。

猜你喜欢

转载自blog.csdn.net/qq_37543025/article/details/86656981
今日推荐