當前位置:編程學習大全網 - 編程語言 - vc編程,看看我這樣寫喲什麽錯誤呢

vc編程,看看我這樣寫喲什麽錯誤呢

VC真是壹個非常笨,非常不友好的工具,還是這樣說,VC(MFC)和現在流行的。net framework java比起來就想石器時代跟工業時代相比壹樣

WC_DEFAULTCHAR, strWideChar, strWideChar.GetLength(), (char *)buf, //轉換到緩沖區中 20, //最多個字節 0, 0 );

同樣的,妳接收到的字符串想要在界面正常顯示,還必須把它轉換成寬字節表示:

char chBytes[8]; memcpy(chBytes,”aaaaaaa\0”,8); WCHAR wch[9]; n = MultiByteToWideChar( //轉換Unicode到Ansi CP_ACP, 0, chBytes, 8, wch, //轉換到緩沖區中 8 //最多個字節 ); wch[n] = ‘\0‘;

這樣每次從界面取數據和把數據顯示到界面上都要先做處理,但是也可以把編譯環境設置成“多字符集”(Multi-Byte Character Set),就可以避免這樣轉換來轉換去(可惜我發現的時候代碼已經差不多寫完了)。就是在“Project-Configuration Properties-General-Character Set,選擇”Use Unicode Character Set“就是使用Uncode字符集,選擇” Use Multi-Byte Character Set“就是多字節字符集。

第二次中招,god,花了我好長時間才找到問題:

我在CodeProject上找了壹個很厚道的老外寫的壹個繼承了CDialog窗體類CResizableDialog的源碼,這個類的作用是使MFC的窗體放大縮小時,窗體上的控件可以定位(Auchor),不要小看這個小小的每天都要用到的功能,用MFC實現真的很麻煩。很佩服那個老外寫了那麽多代碼(當然跟他們的條件有關,資本主義國家的工人隨便找個工作就可以衣食無憂,病了政府照顧,我們做“挨踢”的活得像民工壹樣,當然沒有那個閑情去寫那麽好的代碼免費給別人使用,這是題外話)。

我拿了那個現成的工程,直接在我的工程裏引用他的工程。Everything works perfect.直到我把項目發布成Release的,雙擊運行後沒有任何反應,Very weird!後來我用MessageBox打印消息,發現運行到DoModal函數裏面就沒有出來,程序直接退出了!使用try,catch都得不到錯誤!因為我的窗體是繼承老外寫的窗體類來的,原先繼承CDialog是好好的,問題肯定在他的工程裏面,可是他給的示例程序沒有任何問題啊。MFC出錯的時候是很要命的,它不會給妳任何提示,它就是不幹了!

我又拿壹個前的測試程序,讓它從CResizableDialog繼承,也沒有任何問題。

簡直頭大了、無語了,不知道哪裏出現了問題,Release又不能像Debug那樣調試,打了壹堆MessageBox後還是不知道問題出現在哪裏。憑著經驗,可以知道程序中可能出現了內存的越界訪問什麽的致命錯誤,才會導致程序“壹聲不吭”地退出,但是究竟哪裏出了問題呢?

就在束手無策的時候,我發現調用CResizableDialog的成員函數EnableSaveRestore會引發鏈接錯誤:“未定義的外部符號”,不引用它不會出錯,測試程序引用它沒有任何錯誤。通常這個錯誤造成是因為引用函數在。h文件裏聲明了,但是在。cpp裏面沒有定義,或者。cpp文件裏的定義和。h上的參數對不上。但是此時不可能是這個錯誤,因為測試程序沒有錯誤啊。直覺告訴我這是解決“Release後程序直接退出的關鍵”,說不定這個函數調用的問題解決了Release的問題也解決了。

MFC真是很強大,它強大得不但“像迷宮壹樣,裏面有怪獸,進去壹不小心就永遠出不來”,而且它讓妳當遇到怪獸的時候總是給妳壹點點星光,只要妳不放棄,奇跡就會出現,妳就會練成絕世神功。這跟武俠小說是相通的,主人公每次到了生死關頭就會出現奇跡,成為天下無敵的高手。看看我怎麽找到解決方法的,Very tricky。

既然調用EnableSaveRestore出現了不該出現的錯誤,那麽就從這個函數開始找。這個函數是這樣的:

.h文件聲明 void EnableSaveRestore(LPCTSTR pszSection, BOOL bRectOnly = FALSE); .cpp文件定義 void CResizableDialog::EnableSaveRestore(LPCTSTR pszSection, BOOL bRectOnly/* = FALSE */)

上面的代碼沒有任何錯誤,既然沒有錯誤,就要用使用以下方法來找:

1.重新為CResizableDialog寫壹個函數,它沒有參數的,調用它,發現沒有錯誤,看來參數有問題。

2.既然沒有參數的函數沒有錯誤,就把出問題的函數參數去掉吧,竟然也沒有錯誤!那問題就肯定是出在參數上。

3.去掉其中壹個參數,測試發現是LPCTSTR pszSection的問題,而不是BOOL bRectOnly的問題。

4.既然這樣,那就換壹種表示吧,把LPCTSTR pszSection換成WCHAR* pszSection,運行它,竟然不出錯了!翻開MFC宏定義,就會發現其實LPCTSTR和WCHAR*是壹樣的,MFC真是freak!

5.但是這個函數功能還是不正常,斷點進入那個函數裏面發現傳進去的字符串只有壹個字符了,這種情況就是寬字符當成短字符時,第二個字節的\0當成了字符串的截止字符了,也就是說,這個函數裏采用的是短字符(多字符集Multi Byte)處理的。

6.我的工程采用的是寬字符集(Unicode Char)的,檢查設置,原來那個老外是用VC6編的,默認是使用多字符集(Multi Byte)的,VC真是笨啊,兩個Project在壹個Solution裏面完全不同的設置竟然沒有任何提示,簡直把我弄死了!

7.把引用工程也改成使用Unicode字符集,並且把函數EnableSaveRestore WCHAR* pszSection恢復原樣,搞定!果然不出我所料,Release也沒有問題了!我用以前的那個測試程序來使剛好以前把它設成Multi Byte,所以也沒有錯誤,Damn!

僅僅是壹個設置啊,如果VC出錯提示稍微好的,至少字符集不匹配不要說成“未定義的外部符號”也好用壹點啊,難怪現在用VC的人越來越少了!

註:通常說的VC不是指使用。net framework的VC,那個很簡單,內存都不用管,通常是指非托管的VC。

  • 上一篇:北大青鳥java培訓:零基礎如何開始學習編程?
  • 下一篇:蘋果id鎖破解
  • copyright 2024編程學習大全網