簡體   English   中英

如何解決AMD64 Win Python35_d.lib中缺少PyModule_Create2的問題?

[英]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庫的特殊版本。 涉及幾個步驟:

  • 運行'bootstrap.bat --with-python =“ C:\\ Program Files \\ Python35”'
  • 在主目錄中編輯user-config.jam,使其看起來像(空格很重要)
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 ;
  • 使用額外的選項“ python-debugging = on”調用b2.exe,如下所示
.\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”。)

  • 最后一步是確保要構建的擴展模塊鏈接到“正確的”庫。 我發現定義預處理器符號BOOST_DEBUG_PYTHON和BOOST_LINKING_PYTHON以及預期的_DEBUG就足夠了,因為在config / auto_link.hpp中有以下幾行
#        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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM