[工程疑難]windows版的gvim不能補全wxPython的問題

來源:互聯網
上載者:User

這個問題困擾我許久,終於解決了。

 

首先,在python解譯器中直接import wx,是沒有問題的,能夠正常使用wxPython,說明安裝wxPython成功了的。

但是,開啟gvim,編輯一個.py檔案,在指令碼中import wx,聲明一個變數app = wx.App(),再鍵入app.,結果沒有彈出自動補全菜單。

要知道,物件導向gui庫十分龐大,不太可能去記類的方法,因此,自動補全所提供的列表,非常重要。

 

gvim對python的自動補全支援在檔案pythoncomplete.vim中實現,瀏覽一下知道,補全功能依賴於動態語言的反射(eval、dir),如果該功能有問題的話,調用python函數showdbg就可以調查。

好,在gvim的命令欄鍵入:

:py showdbg()

從其中的資訊可以得知,gvim內建的python解譯器在import wx時失敗了。

再在gvim中測試一下:

:py import wx

提示import _core_時找不到模組。

 

用ollydbg附加到gvim中,發現python用LoadLibraryEx(參數LOAD_WITH_ALTERED_SEARCH_PATH)載入_core_.pyd,結果失敗了,Win32錯誤碼為ERROR_MOD_NOT_FOUND。自己寫一個C++測試程式(使用的vc版本應該和編譯wxPython的vc版本相同),用同樣的參數調用LoadLibraryEx,卻能成功。

 

總之,到這裡,確認gvim不能自動補全的原因是gvim內建的python解譯器import wx失敗,而後者import wx失敗又是因為windows在用LoadLibraryEx載入_core_.pyd時失敗。

 

觀察_core_.pyd這個動態庫的依賴項,主要缺失項是msvcr90.dll、msvcp90.dll(我用的vc2008編譯wxPython)。拷貝這兩個檔案到_core_.pyd所在目錄,再在gvim的命令列中鍵入:py import wx,仍然報錯,不過這次是彈出windows訊息框,說“An application has made an attempt to load the C runtime library without using a manifest”。

 

開啟_core_.pyd這個檔案,搜尋索引鍵“manifest”,看到內嵌的manifest,發現僅依賴於“Microsoft.Windows.Common-Controls”,對比編譯wxPython時產生的其他manifest檔案知道,還少了“Microsoft.VC90.CRT”項,從我的wxPython的lib\vc_dll目錄中隨便拷貝一個manifest檔案(如wxmsw28uh_adv_vc.dll.manifest),用mt工具嵌入_core_.pyd中即可:

mt -nologo -manifest wxmsw28uh_adv_vc.dll.manifest -outputresource:_core_.pyd;2

再一測試發現,所有的pyd檔案的內嵌manifest都有問題,用上面的命令依次更新每個pyd檔案即可。

 

總結一下,我在windows下用gvim編寫python代碼,訪問wxPython庫時gvim內建的自動補全失效,原因是用wxPython 2.8.12.1官方內建的編譯指令碼輸出的*.pyd檔案都被嵌入了錯誤的manifest,修複方法是,找一個編譯wxPython時產生的完整的manifest依次嵌入所有的*.pyd檔案。

 

作為參考,我所嵌入的manifest檔案內容(當然和我所使用的vc版本有關):

<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level='asInvoker' uiAccess='false' />
</requestedPrivileges>
</security>
</trustInfo>
<dependency>
<dependentAssembly>
<assemblyIdentity type='win32' name='Microsoft.VC90.CRT' version='9.0.21022.8' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' />
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly>
<assemblyIdentity type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*' />
</dependentAssembly>
</dependency>
</assembly>

 

另外,之所以python解譯器和其他python容器程式能夠成功import wx,是因為他們在import wx之前已經載入好了正確版本的crt(比如python解譯器本身就是vc2008編譯的) ,而gvim是c語言編寫的,在import wx->import _core_的時候才第一次載入c++庫,此時殘缺的內嵌manifest會導致錯誤。

 

雖然是wxPython的bug,但還是得說微軟2。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.