Variant 和 const wchar_t* 的 bug? |
|
aftcast
站務副站長 發表:81 回覆:1485 積分:1763 註冊:2002-11-21 發送簡訊給我 |
最近用bcb寫com元件,發現其中Variant型別與wchar_t*的轉換有些問題(怪怪的)。 for example: void __fastcall TForm1::Button1Click(TObject *Sender) Variant v1(L"NONO"); ShowMessage(v1.AsType(varString)); } show出來的內容是對的,但在ide 下run卻在離開function時出現了錯誤,好像無法正常的relase一些東西。 若把程式改成 void __fastcall TForm1::Button1Click(TObject *Sender) Variant v1(WideString(L"NONO")); ShowMessage(v1.AsType(varString)); } 可以正常的return。這問題在寫com時的症狀是你無法從com傳出字串,但若在Variant的建構式上先經由widestring建構,再copy至variant就很正常。有點脫褲放屁,但一定要這樣。不知道是什麼問題? 看了相關的variant 建構式中,by value 的方式裡的確是有Variant(wchar_t* const src);可為何一定要經過widestring穩含轉換一次? 不知大家有什麼看法?
------
蕭沖 --All ideas are worthless unless implemented-- C++ Builder Delphi Taiwan G+ 社群 http://bit.ly/cbtaiwan |
aftcast
站務副站長 發表:81 回覆:1485 積分:1763 註冊:2002-11-21 發送簡訊給我 |
打了二次好長的解答研究報告…但都在要傳出的時候不見了…session time out? back 也找不回資料… 打累了,把最後的答案精簡的講一下,想知道深入的請在post出來。 WideString中的方法c_bstr( )傳回的也非code completion上所寫的wchar_t* 而是正統的BSTR。 BSTR與wchar_t*所指的資料內容都是一樣的型別,wchar_t。然而BSTR所配置出來的memory,在字串前有四個byte記載著字串的總byte數。這是二者的不同。以下的程式証明… WideString bs = L"我是蕭沖"; 得到8,即字串總長是8byte。 結論: Variant中的建構式複載wchar_t* 不能放入自己用陣列或是new或是malloc等配發的wchar_t * 指標! 不要被騙了!! 這是很重大的發現!!
蕭沖
------
蕭沖 --All ideas are worthless unless implemented-- C++ Builder Delphi Taiwan G+ 社群 http://bit.ly/cbtaiwan |
aftcast
站務副站長 發表:81 回覆:1485 積分:1763 註冊:2002-11-21 發送簡訊給我 |
|
aftcast
站務副站長 發表:81 回覆:1485 積分:1763 註冊:2002-11-21 發送簡訊給我 |
程式有點小貼錯… 重貼 (重打太多次,有點心浮 xp)
WideString bs = L"我是蕭沖"; BSTR s = bs.c_bstr(); // 改寫成 wchar_t* s = bs.c_bstr() 也是一樣的 char **p=(char**)&s; unsigned long *z=(unsigned long *)(*p-4); unsigned long j=*z; // 取字串前的四個byte ShowMessage(j);
------
蕭沖 --All ideas are worthless unless implemented-- C++ Builder Delphi Taiwan G+ 社群 http://bit.ly/cbtaiwan |
aftcast
站務副站長 發表:81 回覆:1485 積分:1763 註冊:2002-11-21 發送簡訊給我 |
事隔4年多了,又發覺一個WideString的問題。平常很少機會用到它,所以都沒仔細的去了解。
這次發現的問題: [code cpp] WideString ws(L"\x1234"); WideString ws2(L"good"); ws = "select * from"; ws = ws2.c_bstr(); ws = L"select * from 222"; [/code] 當執行最後一行時,就一定會出錯。可是好像直覺是可以的。查了help檔再次了解到,原來 = 的複載裡沒有定義 wchar_t* 的型別。 可是為什麼compile時是正確的,並沒有什麼型別錯誤。於是叫出cpu來debug。發現,原來compiler會自動的加一些料,它的確就是使用了 wchar_t* 的 = operator。疑? 這個型別在help檔裡根本沒提到。為何有這個藏著的方法呢? 再深入的去了解… 唉呀,原來這個隱藏的 方法 是用在 bstr 的。所以你看上面的程式碼,當ws = ws2.c_bstr(); 這行就不會出錯。但搞一個正統的wchar_t* 的帶入就掛點。 所以,我又回憶起以前有類似追個這樣的事…就找到我篇了。人老了還是會忘了些東西… 結論,要使用 WideString 的 = 複載方法時,一定要: WideString ws; ws = WideString(L"hello"); 而不能 ws = L"hello"; 因為第二種compiler不會說型別有誤(因為有內藏),但run下去就死。 最後還是一句話: 在bcb裡, wchar_t * 與 bstr 常常以同樣的宣告出現,但實則不一樣。要注意! 所見的wchar_t* 的參數 常常很有可能是指bstr !
------
蕭沖 --All ideas are worthless unless implemented-- C++ Builder Delphi Taiwan G+ 社群 http://bit.ly/cbtaiwan |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |