又黄又www的网站_青青草.com_在线亚洲美日韩_九九九国产视频_√天堂8资源中文在线_一区二区三区免费网站_久久久久国产一区二区三区_人妻激情偷乱视频一区二区三区_一本到在线视频

C技巧:請?zhí)貏e注意VC字符集設(shè)置

發(fā)布時(shí)間:2011-08-29 共1頁

  VC真是一個(gè)非常笨,非常不友好的工具,還是這樣說,VC(MFC)和現(xiàn)在流行的.net framework java比起來就想石器時(shí)代跟工業(yè)時(shí)代相比一樣!
  接觸MFC也有幾年了,為了它有過加班、有過熬夜、甚至通宵,代碼沒有十萬行也應(yīng)該有幾萬行了。但是MFC就是這么牛,它牛得不但令新手忘而卻步,而且常常令有經(jīng)驗(yàn)的軟件工程師也栽跟斗。最近由于一個(gè)小小的環(huán)境設(shè)置設(shè)置問題花了很多時(shí)間,這跟用慣了VC6突然轉(zhuǎn)到VC2005有關(guān),但關(guān)鍵還是VC實(shí)在太笨了,它讓我在一周內(nèi)連續(xù)兩中招次!
  第一次中招是這樣的,很簡單:
  我不知道VC.net2005默認(rèn)工程默認(rèn)設(shè)置是采用“Unicode字符集”(Unicode Character Set)的,以前用VC6工程的時(shí)候默認(rèn)是“多字符集”(Multi-Byte Character Set)的。以前也沒有用過VC.net2005啊,認(rèn)為.net是用來在framework上面編程的,在MFC上編程沒有必要打開龐的.net2005,把機(jī)器弄得像牛拉車一樣。
  聲明了一個(gè)CString,按計(jì)劃給它賦值,就像下面:
  CString s;
  s.Format(“count = %d”,count);
  按經(jīng)驗(yàn)這肯定不會有錯(cuò)誤的,但是不好意思,編譯錯(cuò)誤,因?yàn)檫@是我的環(huán)境采用的Unicode字符集的,而我給CString的Format函數(shù)是“多字符集”(Multi-Byte)所以編譯不通過,要知道在這種設(shè)置下使用MessageBox(“ddd”);編譯是不會通過的,因?yàn)橄到y(tǒng)調(diào)用的是MessageBoxW,即Unicode寬字符集的那個(gè)函數(shù)。
  還好我根據(jù)編譯器的提示把s.Format(“count = %d”,count);改成s.Format(_T(“count = %d”,count);就搞定了,_T代表一個(gè)宏,宏的意思就是把字符串轉(zhuǎn)成寬字符表示。同樣的,MessageBox(“ddd”);可以為MessageBox(_T(“ddd”));
  但是還有個(gè)問題就是,所有窗體顯示的東西都是寬字符的,例如a在內(nèi)存里就是a\0兩個(gè)字節(jié),前面一個(gè)字節(jié)a后面是\0,提示當(dāng)從窗體取下數(shù)據(jù)(例如用戶輸入)要跟其他平臺交互時(shí),例如網(wǎng)絡(luò)傳輸?shù)竭h(yuǎn)端機(jī)器。如果那邊使用的不是Unicode字符集,就會出問題,為了使界面和后臺傳輸一致,只好使用把寬字符轉(zhuǎn)換成多字符集表示:
  CString strWideChar;
  strWideChar.Format(_T(“這是寬字節(jié)哦”));
  char buf[20];
  memset(buf,0,20);
  WideCharToMultiByte( //轉(zhuǎn)換Unicode到Ansi
  CP_ACP,
  WC_COMPOSITECHECK | WC_DEFAULTCHAR,
  strWideChar,
  strWideChar.GetLength(),
  (char *)buf, //轉(zhuǎn)換到緩沖區(qū)中
  20, //最多個(gè)字節(jié)
  0,
  0
  );
  同樣的,你接收到的字符串想要在界面正常顯示,還必須把它轉(zhuǎn)換成寬字節(jié)表示(煩吧?):
  char chBytes[8];
  memcpy(chBytes,”aaaaaaa\0”,8);
  WCHAR wch[9];
  n = MultiByteToWideChar( //轉(zhuǎn)換Unicode到Ansi
  CP_ACP,
  0,
  chBytes,
  8,
  wch, //轉(zhuǎn)換到緩沖區(qū)中
  8 //最多個(gè)字節(jié)
  );
  wch[n] = ’\0’;
  這樣每次從界面取數(shù)據(jù)和把數(shù)據(jù)顯示到界面上都要先做處理,但是也可以把編譯環(huán)境設(shè)置成“多字符集”(Multi-Byte Character Set),就可以避免這樣轉(zhuǎn)換來轉(zhuǎn)換去(可惜我發(fā)現(xiàn)的時(shí)候代碼已經(jīng)差不多寫完了)。就是在”Project->Configuration Properties->General->Character Set,選擇“Use Unicode Character Set”就是使用Uncode字符集,選擇” Use Multi-Byte Character Set”就是多字節(jié)字符集。
  第二次中招,god,花了我好長時(shí)間才找到問題:
  我在CodeProject上找了一個(gè)很厚道的老外寫的一個(gè)繼承了CDialog窗體類CResizableDialog的源碼,這個(gè)類的作用是使MFC的窗體放縮小時(shí),窗體上的控件可以定位(Auchor),不要小看這個(gè)小小的每天都要用到的功能,用MFC實(shí)現(xiàn)真的很麻煩。很佩服那個(gè)老外寫了那么多代碼(當(dāng)然跟他們的條件有關(guān),資本主義國家的工人隨便找個(gè)工作就可以衣食無憂,病了政府照顧,我們做“挨踢”的活得像民工一樣,當(dāng)然沒有那個(gè)閑情去寫那么好的代碼免費(fèi)給別人使用,這是題外話)。
  我拿了那個(gè)現(xiàn)成的工程,直接在我的工程里引用他的工程。Everything works perfect。直到我把項(xiàng)目發(fā)布成Release的,雙擊運(yùn)行后沒有任何反應(yīng),Very weird!后來我用MessageBox打印消息,發(fā)現(xiàn)運(yùn)行到DoModal函數(shù)里面就沒有出來,程序直接退出了!使用try,catch都得不到錯(cuò)誤!因?yàn)槲业拇绑w是繼承老外寫的窗體類來的,原先繼承CDialog是好好的,問題肯定在他的工程里面,可是他給的示例程序沒有任何問題啊。MFC出錯(cuò)的時(shí)候是很要命的,它不會給你任何提示,它就是不干了!
  我又拿一個(gè)前的測試程序,讓它從CResizableDialog繼承,也沒有任何問題。
  簡直頭了、無語了,不知道哪里出現(xiàn)了問題,Release又不能像Debug那樣調(diào)試,打了一堆MessageBox后還是不知道問題出現(xiàn)在哪里。憑著經(jīng)驗(yàn),可以知道程序中可能出現(xiàn)了內(nèi)存的越界訪問什么的致命錯(cuò)誤,才會導(dǎo)致程序“一聲不吭”地退出,但是究竟哪里出了問題呢?
  就在束手無策的時(shí)候,我發(fā)現(xiàn)調(diào)用CResizableDialog的成員函數(shù)EnableSaveRestore會引發(fā)鏈接錯(cuò)誤:“未定義的外部符號”,不引用它不會出錯(cuò),測試程序引用它沒有任何錯(cuò)誤。通常這個(gè)錯(cuò)誤造成是因?yàn)橐煤瘮?shù)在.h文件里聲明了,但是在.cpp里面沒有定義,或者.cpp文件里的定義和.h上的參數(shù)對不上。但是此時(shí)不可能是這個(gè)錯(cuò)誤,因?yàn)闇y試程序沒有錯(cuò)誤啊。直覺告訴我這是解決“Release后程序直接退出的關(guān)鍵”,說不定這個(gè)函數(shù)調(diào)用的問題解決了Release的問題也解決了。
  MFC真是很強(qiáng),它強(qiáng)得不但“像迷宮一樣,里面有怪獸,進(jìn)去一不小心就永遠(yuǎn)出不來”,而且它讓你當(dāng)遇到怪獸的時(shí)候總是給你一點(diǎn)點(diǎn)星光,只要你不放棄,奇跡就會出現(xiàn),你就會練成絕世神功。這跟武俠小說是相通的,主人公每次到了生死關(guān)頭就會出現(xiàn)奇跡,成為天下無敵的高手??纯次以趺凑业浇鉀Q方法的,Very tricky:
  既然調(diào)用EnableSaveRestore出現(xiàn)了不該出現(xiàn)的錯(cuò)誤,那么就從這個(gè)函數(shù)開始找。這個(gè)函數(shù)是這樣的:
  .h文件聲明
  void EnableSaveRestore(LPCTSTR pszSection, BOOL bRectOnly = FALSE);
  .cpp文件定義
  void CResizableDialog::EnableSaveRestore(LPCTSTR pszSection, BOOL bRectOnly/* = FALSE */)
  {
  m_sSection = pszSection;
  m_bEnableSaveRestore = TRUE;
  m_bRectOnly = bRectOnly;
  // restore immediately
  LoadWindowRect(pszSection, bRectOnly);
  }
  上面的代碼沒有任何錯(cuò)誤,既然沒有錯(cuò)誤,就要用使用以下方法來找:
  1.重新為CResizableDialog寫一個(gè)函數(shù),它沒有參數(shù)的,調(diào)用它,發(fā)現(xiàn)沒有錯(cuò)誤,看來參數(shù)有問題。
  2.既然沒有參數(shù)的函數(shù)沒有錯(cuò)誤,就把出問題的函數(shù)參數(shù)去掉吧,竟然也沒有錯(cuò)誤!那問題就肯定是出在參數(shù)上。
  3.去掉其中一個(gè)參數(shù),測試發(fā)現(xiàn)是LPCTSTR pszSection的問題,而不是BOOL bRectOnly的問題。
  4.既然這樣,那就換一種表示吧,把LPCTSTR pszSection換成WCHAR* pszSection,運(yùn)行它,竟然不出錯(cuò)了!翻開MFC宏定義,就會發(fā)現(xiàn)其實(shí)LPCTSTR和WCHAR*是一樣的,MFC真是freak!
  5.但是這個(gè)函數(shù)功能還是不正常,斷點(diǎn)進(jìn)入那個(gè)函數(shù)里面發(fā)現(xiàn)傳進(jìn)去的字符串只有一個(gè)字符了,這種情況就是寬字符當(dāng)成短字符時(shí),第二個(gè)字節(jié)的\0當(dāng)成了字符串的截止字符了,也就是說,這個(gè)函數(shù)里采用的是短字符(多字符集Multi Byte)處理的。
  6.我的工程采用的是寬字符集(Unicode Char)的,檢查設(shè)置,原來那個(gè)老外是用VC6編的,默認(rèn)是使用多字符集(Multi Byte)的,VC真是笨啊,兩個(gè)Project在一個(gè)Solution里面完全不同的設(shè)置竟然沒有任何提示,簡直把我弄死了!
  7.把引用工程也改成使用Unicode字符集,并且把函數(shù)EnableSaveRestore WCHAR* pszSection恢復(fù)原樣,搞定!果然不出我所料,Release也沒有問題了!我用以前的那個(gè)測試程序來使剛好以前把它設(shè)成Multi Byte,所以也沒有錯(cuò)誤,Damn!
  僅僅是一個(gè)設(shè)置啊,如果VC出錯(cuò)提示稍微好的,至少字符集不匹配不要說成“未定義的外部符號”也好用一點(diǎn)啊,難怪現(xiàn)在用VC的人越來越少了!
  注:通常說的VC不是指使用.net framework的VC,那個(gè)很簡單,內(nèi)存都不用管,通常是指非托管的VC。

百分百考試網(wǎng) 考試寶典

立即免費(fèi)試用
伊人网在线综合| 久久国产精品久久久久| 一区二区三区欧美在线| 国产一区二区在线视频聊天| 国产蜜臀一区二区打屁股调教| 麻豆中文一区二区| 中文字幕精品久久久久| 亚洲日本黄色片| 天堂在线观看视频观看www| japanese国产精品| 欧美一区二区大片| 男女高潮又爽又黄又无遮挡| 另类视频欧美| 免费看成人吃奶视频在线| 欧美精品精品一区| 免费看一级大黄情大片| 国产偷窥女洗浴在线观看亚洲| 美国成人xxx| 91精品国产一区二区三区| 欧美日韩激情视频在线观看| 91九色蝌蚪| 欧美99久久| 神马久久桃色视频| 扒开jk护士狂揉免费| 天堂资源最新在线| 国产成人亚洲综合a∨婷婷图片| 日韩**中文字幕毛片| 国产一级在线视频| 黄频免费在线观看| 亚洲五码中文字幕| 嫩草影院中文字幕| 天堂网在线观看| 亚洲欧美网站| 九九热精品在线| www青青草原| 日韩深夜视频| 欧美日韩一区二区精品| 美女日批免费视频| 午夜大尺度福利视频| 久久成人免费电影| 91情侣偷在线精品国产| 亚洲中文一区二区三区| 天堂精品久久久久| 欧美草草影院在线视频| 荫蒂被男人添免费视频| 国产福利第一视频在线播放| 久久久久国产精品厨房| 亚洲成人一区二区三区| 亚洲人的天堂男人爽爽爽| 婷婷精品进入| 久久久久久成人精品| 久久精品无码人妻| 四虎影视精品永久在线观看| 7777女厕盗摄久久久| 日本亚洲一区二区三区| 国产美女视频一区二区三区| 国产精品久久久久精k8| 黄色片免费在线观看视频| wwwxx在线观看| 国产综合久久久久久久久久久久| 国产成人看片| 日韩8x8x| 日日摸夜夜添夜夜添精品视频| 国产欧美日韩精品在线观看| 网友自拍一区| 日韩一级在线| wwwwwww色| 日本成人一级片| 男人天堂av电影| 在线免费观看av的网站| 亚洲高清视频一区二区| 亚洲欧美日韩天堂| 国产成+人+日韩+欧美+亚洲| 国产一区影院| 中文字幕有码在线观看| а√最新版天堂中文在线| 亚洲AV无码国产精品午夜字幕| 国产男女无遮挡| 97超级碰碰| 日韩在线观看免费网站| 97香蕉久久超级碰碰高清版| 成人情趣片在线观看免费| 亚洲视频综合网| 欧美高清www午色夜在线视频| 日本精品视频一区二区三区| 亚洲一区二区三区四区的 | 久久久久久国产精品免费播放| 中文字幕一区二区三区乱码不卡| 日韩国产欧美亚洲| 亚洲色成人www永久在线观看 | 亚洲精品视频网址| 亚洲熟妇一区二区| 国语对白做受xxxxx在线中国| 欧美图片激情小说| 国产精品久久久久一区二区| 欧美大片在线观看| 欧美午夜片在线免费观看| 日韩精品一区二区三区三区免费 | 国产精品99视频| 999久久久国产精品| 91最新在线| 午夜视频在线观看免费视频| av在线中文| 鲁鲁在线中文| 欧美大片网址| www.一区二区| 7777女厕盗摄久久久| 精品成人佐山爱一区二区| 91热精品视频| wwwwwxxxx日本| 久久机热这里只有精品| 五月婷婷丁香花| 少妇与大狼拘作爱性a| jizzjizzjizzjizz日本| 久草在线新视觉| 国产黄在线看| 欧美电影免费观看| 欧美三级伦理在线| 青青国产91久久久久久| 亚洲欧美综合久久久| 最新国产精品视频| 一本色道久久综合狠狠躁的番外| 91精品导航| 北条麻妃一区二区三区在线观看| 欧美黑粗硬大| 亚洲图色一区二区三区| 亚洲精品在线观看91| 九一九一国产精品| 亚洲欧美日韩国产一区二区三区| 亚洲人成精品久久久久久| 亚洲国产黄色片| 成人中心免费视频| 中文字幕在线播放视频| 最近2018年在线中文字幕高清| 免费在线观看麻豆视频| 国产毛片精品| 国产精品免费久久| 欧美成人sm免费视频| 欧美在线观看黄| 免费毛片视频网站| 亚洲AV无码成人片在线观看| √天堂资源中文www| 九色在线免费| 久久资源综合| 极品少妇一区二区| 一区二区三区精品久久久| xvideos亚洲| 国产一区免费| 日韩av电影免费在线| 国产精品h视频| 天天干天天综合| 国产熟女一区二区| 依依成人综合网| 日本国产在线观看| 福利视频网站| 91精品xxx在线观看| 天堂影院一区二区| 成人性视频免费网站| 欧美在线不卡一区| 国产精品久久久久久久久久久久久久 | 男女男精品视频网| 亚洲成人黄色网址| 日本精品免费在线观看| www.精品久久| 日韩在线资源| 国产日韩一区| 天天影视涩香欲综合网 | 久久久久久伊人| 日韩视频在线观看视频| 欧美bbbbb性bbbbb视频| 免费观看a视频| 黄色视屏网站在线免费观看| 国产aⅴ精品一区二区四区| 国产农村妇女毛片精品久久莱园子| 国产亚洲制服色| 欧美大片欧美激情性色a∨久久| 中文字幕无码精品亚洲35| 四虎影院在线免费播放| 尤物在线观看| 欧美成年网站| 久久亚洲综合av| 日韩av在线天堂网| 日本成人在线视频网址| 天天操天天摸天天爽| 在线视频日韩欧美| www.4hu95.com四虎| 少妇太紧太爽又黄又硬又爽| 国产一级激情| 在线免费观看黄色网址| 日韩激情精品| 欧美精品偷拍| 97se亚洲国产综合自在线| 老司机精品视频在线观看6| 麻豆成人久久精品二区三区红 | 2021狠狠干| 国产成人在线免费视频| 91精品久久久久久9s密挑| 一区二区亚洲| 国产一区二区三区在线看| 日韩精品 欧美|