我正在尝试调试在32位Python 2.7中运行良好的扩展模块,但在64位Python 3.5中效果不是很好。
我使用过Python.org的AMD64 Web安装程序,但在链接中我得到了
__imp_PyModule_Create2 (referenced in libboost_python-vc120-mt-gd-1_57.lib(module.obj))
尚未解决。这是唯一尚未解决的符号。
这是故意的吗?我看到一个旧的错误报告似乎表明Stable ABI免于调试版本。 (这就是我在SO上发帖而不是提交错误报告的原因)如果是故意的,是否可以与python35_d.lib和python35.lib链接,还是有另一种解决方法?
答案 0 :(得分:4)
我在这里发现了这个问题; AMD64因素无关紧要。
关键是Boost Python库需要链接Python的Release版本,即使它是Boost Python的调试版本。通过尝试链接依赖于Boost Python的扩展模块,Boost的
config/auto_link.hpp
将(默认情况下)创建链接依赖项 - 使用
#pragma comment(lib, string_of_library_name)
- 在python35.lib上。如果在您的扩展模块的makefile中指定了python35_d.lib,期望您的python将被调用为python35_d.exe,这是个坏消息。
我通过运行
找到了这个dumpbin /EXPORTS python35.lib > python35_exp.txt
dumpbin /EXPORTS python35_d.lib > python35_d_exp.txt
并比较两者。关键区别在于发布版本导出符号PyModule_Create2和PyModule_FromDefAndSpec2,而调试版本导出PyModule_Create2TraceRefs和PyModule_FromDefAndSpec2TraceRefs。这是Python开发人员明确的慎重选择,以确保调试扩展模块仅适用于调试Python。在Python源代码中,include / object.h中的第一行是
/* Py_DEBUG implies Py_TRACE_REFS. */
#if defined(Py_DEBUG) && !defined(Py_TRACE_REFS)
#define Py_TRACE_REFS
#endif
赠品位于include / modsupport.h
#ifdef Py_TRACE_REFS
/* When we are tracing reference counts, rename module creation functions so
modules compiled with incompatible settings will generate a
link-time error. */
#define PyModule_Create2 PyModule_Create2TraceRefs
#define PyModule_FromDefAndSpec2 PyModule_FromDefAndSpec2TraceRefs
#endif
解决方案是构建特定版本的Boost库,专门链接到python35_d.lib。涉及几个步骤:
using python : 3.5 : C:\\PROGRA~1\\Python35 ; using python : 2.7 : C:\\Python27 ; using python : 3.5 : C:\\PROGRA~1\\Python35\\python_d : # includes : # libs : <python-debugging>on ;
.\b2.exe toolset=msvc-12.0 threading=multi variant=debug address-model=64 --with-python --debug-configuration python-debugging=on stage
请注意,要解决依赖关系,您还必须编译date_time,thread,chrono,filesystem和system(只需将“--with-python”替换为“--with-otherlibname”。)
# if defined(_DEBUG) && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) # define BOOST_LIB_RT_OPT "-gyd" # elif defined(_DEBUG) # define BOOST_LIB_RT_OPT "-gd" # else # define BOOST_LIB_RT_OPT # endif
应该这样做 - 一个Python扩展模块的调试版本,它应该编译并链接一个Boost Python库,它希望链接到python35_d.lib,并且当用python_d调用的脚本加载时不会崩溃。 EXE。