天天看點

STLFilt for VC6.0 安裝工具

    【摘要】在《C++ Templates》(David Vandevoorde, Nicolai M.Josuttis)一書的6.6.1節中,介紹了一個過濾編譯STL代碼的錯誤資訊的小工具:STLFilt(由 Leor Zolman 編寫)。由于STL代碼的錯誤和警告資訊非常繁雜冗長(尤其在VC6.0中),不利于程式員閱讀,是以這個工具顯得很有用。不過它的安裝和配置卻很繁瑣。工具包中提供了很多個 readme 英文文檔來指導使用者進行安裝和配置,但是必須要關注的配置檔案細節等等,仍然需要耗費很大精力(我花了好幾十分鐘)。如果給另一台電腦安裝,盡管已經有所熟悉,但是又要耗費一定的精力。是以我寫這篇文章,開發了一個簡易的小工具來替使用者完成繁瑣的複制和配置工作。

    為什麼作者沒有提供一個簡易的安裝程式呢?作者在說明(QUICKSTART.txt)中是這樣說的:

    ==========================================================================

    Q: Why isn't there a nice, simple-to-use SETUP.EXE facility for this tool?

    A: I'm not confident enough with "setup" utilities to make certain that one I provide doesn't have the potential to scramble the guts of

your computer. If you do the installation manually, that absolutely guarantees you'll have the ability to UN-do what you've done if you want, no fancy uninstaller tools required. If you are a practicing or aspiring software developer, you probably won't find these direction overly complicated. If you're NOT, you probably wouldn't be here trying to install a package for filtering STL-related C++ error messages in the first place.

    作者說,(他擔心把把你的電腦搞亂?)如果這一切配置工作都是由使用者手工完成的,那麼使用者就能夠完全的“UNDO”這個步驟。如果你是一個專業的程式員,你應該發現這個步驟不是很複雜。如果你覺得這個步驟太麻煩了,那麼多半你也不會出現在這裡并且試圖去安裝他。

    但我花了一點耐心按照QuickStart.txt中的指導,一步步配置好以後,我覺得這個過程是可以用一個可視化工具來簡化的,是以我現在來做了這個工作。我隻給我的VC6.0配置了STLFilt工具,從說明來看,STLFilt還可以多平台使用(這裡的多平台是針對多種IDE,編譯工具而言),不過就目前來看我寫的工具隻是預設的配置成為VC6.0使用,因為在VC6中的STL警告和錯誤尤其多,有時産生數百個warning,重新編譯一次消耗的時間很長,是以這個沖突在VC6上尤其突出,在VS2005上暫時還沒發現問題這麼嚴重和突出。是以我寫的自動化安裝工具是針對VC6的。

    安裝條件,你已經安裝過 VC6.0 。對于其他VS版本我沒有認真看過配置的步驟,是以如果你希望配置到其他IDE上,請自行閱讀 stlfilt 的原有說明文檔,然後自己改進我提供的工具。

    安裝 STLFilt For VC6.0 的主要步驟如下:

    (1)下載下傳 ActivePerl 進行安裝。

    這個工具是用來運作 Perl 腳本的(它是免費的)。目前最新的用于x86的版本下載下傳位址:

    (2)運作 stlfilt 檔案夾下的 STLFiltSetup.exe(我寫的小工具) ,點選安裝。

    stlfilt 和 我的安裝工具的下載下傳位址:

     

    操作界面如下所示:

    

STLFilt for VC6.0 安裝工具

    (3)在VC6.0中的 Tools 菜單中添加自定義工具:

      3.1) STLFilt 切換開關(可以在菜單中自由打開或者關閉STLFilt):

      點選 Tools - Customize 菜單,在Tools标簽頁建立一項,名稱輸入"STLFilt ON/OFF";

      3.1.1 指令(Command): ($InstallDir)STLFilt_hoodlum1980.BAT

      3.1.2 參數(Arguments):保留為空

      3.1.3 勾選使用輸出視窗(Use Output Window);

      備注:STLFilt_hoodlum1980.BAT 是我在 STLFilt 的 STLFilt.BAT 的基礎上改造而成,自動根據目前狀态切換狀态(無須顯示指定新的狀态)。

         ($InstallDir) 指的是在安裝STLFilt工具中選擇的 STLFilt 的安裝目錄。

      3.2) MFiltTool (把生成日志(*.plg)的内容過濾後輸出到輸出視窗)。

      備注:由于它是為沒有配置的環境也能使用 STLFilt 而準備的,而我們這裡已經配置過了,是以這個工具可以不添加。

      添加方法和上面類似,名稱輸入"MFiltTool“

      3.2.1 指令(Command): ($InstallDir)MFiltTool.bat

      3.2.2 參數(Arguments):$(WkspDir)\$(WkspName).plg

      3.2.3 勾選使用輸出視窗(Use Output Window);

    注意事項說明:

    (1)為了防止弄亂VC6的CL.EXE版本,建議按照程式自動給出的安裝方式執行安裝或解除安裝。為了更加穩妥起見,可以在安裝前單獨備份CL.EXE,以防止意外。

    (2)安裝工具在解除安裝時,會把複制的檔案删除,并恢複CL.EXE;但是不包含以下動作例如:解除安裝ActivePerl,删除 VC6 的 Tool 菜單下的 STLFilt 相關指令等;這些動作如有需要,應該由使用者自行完成。

    經過以上步驟,現在STLFilt就可以使用了,需要解除安裝的時候再次運作這個工具,點選解除安裝即可。在菜單中使用STLFilt ON/OFF指令可以自由切換狀态。在ON狀态,STL的編譯資訊被過濾後顯示到輸出視窗,在OFF狀态,相當于沒有安裝STLFilt一樣。是以我們可以在使用STL時開啟這個選項,在沒有使用STL的項目中關閉它。此外STLFilt還提供了一個UI小工具(即我在桌面上建立了快捷方式的那個EXE程式),也可以通過右鍵上下文菜單切換STLFilt狀态,并且可以對記憶體中的文本進行過濾處理。由于我們已經配置好了,是以通過 Tools 中的菜單即可操作,這個工具也基本可以不去管他(不需要運作)。

    下面我通過一個簡單的小例子測試下STLFilt的效果,在VC6中建立一個Console程式,輸入代碼如下:

#include "stdafx.h"

#include <map>

#include <string>

using namespace std;

int main(int argc, char* argv[])

{

    map<string, int> _Map;

    _Map.insert("hello", 100);

    return 0;

}

    在 STLFilt 關閉狀态下,編譯這段代碼,VC6的輸出資訊如下:

STLFilt for VC6.0 安裝工具
STLFilt for VC6.0 安裝工具

output_STLFilt_OFF

--------------------Configuration: STL_DEMO_3 - Win32 Debug--------------------

Compiling...

     ****** {BD Software Proxy CL v2.50} STL Message Decryption is Off ******

STL_DEMO_3.cpp

d:\program files\microsoft visual studio\vc98\include\xtree(118) : warning C4786: 'std::_Tree<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,

int>,std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,int,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<int> >::_Kfn,std::less<std::basic_string<char,std::char_traits<cha

r>,std::allocator<char> > >,std::allocator<int> >' : identifier was truncated to '255' characters in the debug information

        d:\program files\microsoft visual studio\vc98\include\map(46) : see reference to class template instantiation 'std::_Tree<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::pair<std::basic_string<char,std::char_traits<

char>,std::allocator<char> > const ,int>,std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,int,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<int> >::_Kfn,std::less<std::ba

sic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<int> >' being compiled

        E:\MyProjects\STL\STL_DEMO_3\STL_DEMO_3.cpp(11) : see reference to class template instantiation 'std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,int,std::less<std::basic_string<char,std::char_traits<char>,std::a

llocator<char> > >,std::allocator<int> >' being compiled

r>,std::allocator<char> > >,std::allocator<int> >::const_iterator' : identifier was truncated to '255' characters in the debug information

r>,std::allocator<char> > >,std::allocator<int> >::iterator' : identifier was truncated to '255' characters in the debug information

r>,std::allocator<char> > >,std::allocator<int> >::_Node' : identifier was truncated to '255' characters in the debug information

E:\MyProjects\STL\STL_DEMO_3\STL_DEMO_3.cpp(12) : error C2664: 'class std::_Tree<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,struct std::pair<class std::basic_string<char,struct std::char_traits<char>,clas

s std::allocator<char> > const ,int>,struct std::map<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,int,struct std::less<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >

 >,class std::allocator<int> >::_Kfn,struct std::less<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,class std::allocator<int> >::iterator __thiscall std::map<class std::basic_string<char,struct std::char_t

raits<char>,class std::allocator<char> >,int,struct std::less<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,class std::allocator<int> >::insert(class std::_Tree<class std::basic_string<char,struct std::cha

r_traits<char>,class std::allocator<char> >,struct std::pair<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const ,int>,struct std::map<class std::basic_string<char,struct std::char_traits<char>,class std::al

locator<char> >,int,struct std::less<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,class std::allocator<int> >::_Kfn,struct std::less<class std::basic_string<char,struct std::char_traits<char>,class std::a

llocator<char> > >,class std::allocator<int> >::iterator,const struct std::pair<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const ,int> &)' : cannot convert parameter 1 from 'char [6]' to 'class std::_Tree

<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,struct std::pair<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const ,int>,struct std::map<class std::basic_string<cha

r,struct std::char_traits<char>,class std::allocator<cha

r> >,int,struct std::less<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,class std::allocator<int> >::_Kfn,struct std::less<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<ch

ar> > >,class std::allocator<int> >::iterator'

        No constructor could take the source type, or constructor overload resolution was ambiguous

Error executing cl.exe.

STL_DEMO_3.exe - 1 error(s), 5 warning(s)

    現在我們把STLFilt開啟,重新編譯,産生的輸出如下:

STLFilt for VC6.0 安裝工具
STLFilt for VC6.0 安裝工具

output_STLFilt_ON

Deleting intermediate files and output files for project 'STL_DEMO_3 - Win32 Debug'.

  ****** {BD Software Proxy CL v2.50} STL Message Decryption is ON! ******

StdAfx.cpp

E:\MyProjects\STL\STL_DEMO_3\STL_DEMO_3.cpp(12): error C2664: 'map<string,int>::iter map<string,int>::insert(map<string,int>::iter,const pair<string,int> &)': cannot convert parameter 1 from 'char [6]' to 'map<string,int>::iter'

    No constructor could take the source type, or constructor overload resolution was ambiguous

STL_DEMO_3.exe - 1 error(s), 0 warning(s)

    我們可以看到,開啟 STLFilt 以後,錯誤資訊變得清晰明了,簡單易讀。備注,要使其通過編譯,需要把Main函數中的第二行代碼修改為:

    _Map.insert(make_pair<string, int>("hello", 100));

    關于安裝工具的原理性說明,安裝工具啟動後, 檢測windows目錄下是否有 "Proxy-CL.ini" 存在,以此判斷 STLFIlt 是否安裝過。安裝工具從系統資料庫中查詢資訊擷取到 VC6.0 和 Perl 的 路徑,雖然使用者可以手工輸入這些路徑,但是除非确有人工幹預的必要,建議使用者使用安裝工具自動擷取到的值。

    STLFilt 工具的原理性說明,STLFilt 使用一個代理CL.EXE 替換 VC6 原來的CL.EXE,在編譯時,代理CL檢測STLFilt的開關狀态,把原始CL産生的輸出資訊重定向到 Perl 中按照指定的規律過濾,然後把過濾後的文本輸出到VC的輸出視窗。

    STLFilt Setup工具的源代碼下載下傳連接配接:

    本文中提到的相關網址:

    (3)STLFilt 聲明(節選自QUICKSTART.txt):

    ======================================================

    BD Software STL Error Message Decryptor for Visual C++

     ******************************************************************

     *  To participate in a forum with other filter users, come visit the

     *  STLFilt section of the BD Software Message Board at:

    -----------THE END------------

        -- By hoodlum1980   2010-8-18

繼續閱讀