[英]How to work around missing PyModule_Create2 in AMD64 Win Python35_d.lib?
我正在嘗試調試一個擴展模塊,該擴展模塊在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,還是有其他方法可以解決此問題?
我在這里發現了問題; 與AMD64因素無關。
關鍵在於,Boost Python庫期望與Python的發行版鏈接,即使它是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
解決方案是構建專門針對python35_d.lib鏈接的Boost庫的特殊版本。 涉及幾個步驟:
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,線程,計時,文件系統和系統(只需將“ --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擴展模塊的調試版本,該模塊應該編譯並鏈接到期望鏈接到python35_d.lib的Boost Python庫,並且在被python_d.exe調用的腳本加載時不會崩潰。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.