一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

字符串轉(zhuǎn)換 BSTR/LPSTR/LPWSTR/Char

 浪子春天 2013-01-16

字符串轉(zhuǎn)換 BSTR/LPSTR/LPWSTR/Char

 一、BSTR、LPSTR和LPWSTR
  在Visual C++.NET的所有編程方式中,我們常常要用到這樣的一些基本字符串類型,如BSTR、LPSTR和LPWSTR等。之所以出現(xiàn)類似上述的這些數(shù)據(jù)類型,是因?yàn)椴煌幊陶Z言之間的數(shù)據(jù)交換以及對ANSI、Unicode和多字節(jié)字符集(MBCS)的支持。
  那么什么是BSTR、LPSTR以及LPWSTR呢?
  BSTR(Basic STRing,Basic字符串)是一個(gè)OLECHAR*類型的Unicode字符串。它被描述成一個(gè)與自動(dòng)化相兼容的類型。由于操作系統(tǒng)提供相應(yīng)的API函數(shù)(如SysAllocString)來管理它以及一些默認(rèn)的調(diào)度代碼,因此BSTR實(shí)際上就是一個(gè)COM字符串,但它卻在自動(dòng)化技術(shù)以外的多種場合下得到廣泛使用。BSTR的結(jié)構(gòu),其中DWORD值是字符串中實(shí)際所占用的字節(jié)數(shù),且它的值是字符串中Unicode字符的兩倍。
  LPSTR和LPWSTR是Win32和VC++所使用的一種字符串?dāng)?shù)據(jù)類型。LPSTR被定義成是一個(gè)指向以NULL(‘\0’)結(jié)尾的8位ANSI字符數(shù)組指針,而LPWSTR是一個(gè)指向以NULL結(jié)尾的16位雙字節(jié)字符數(shù)組指針。在VC++中,還有類似的字符串類型,如LPTSTR、LPCTSTR等。
  例如,LPCTSTR是指“l(fā)ong pointer to a constant generic string”,表示“一個(gè)指向一般字符串常量的長指針類型”,與C/C++的const char*相映射,而LPTSTR映射為 char*。
  一般地,還有下列類型定義:
  #ifdef UNICODE
  typedef LPWSTR LPTSTR;
  typedef LPCWSTR LPCTSTR;
  #else
  typedef LPSTR LPTSTR;
  typedef LPCSTR LPCTSTR;
  #endif
  二、CString、CStringA 和 CStringW
  Visual C++.NET中將CStringT作為ATL和MFC的共享的“一般”字符串類,它有CString、CStringA和CStringW三種形式,分別操作不同字符類型的字符串。這些字符類型是TCHAR、char和wchar_t。TCHAR在Unicode平臺中等同于WCHAR(16位Unicode字符),在ANSI中等價(jià)于char。wchar_t通常定義為unsigned short。由于CString在MFC應(yīng)用程序中經(jīng)常用到,這里不再重復(fù)。
  三、VARIANT、COleVariant 和_variant_t
  在OLE、ActiveX和COM中,VARIANT數(shù)據(jù)類型提供了一種非常有效的機(jī)制,由于它既包含了數(shù)據(jù)本身,也包含了數(shù)據(jù)的類型,因而它可以實(shí)現(xiàn)各種不同的自動(dòng)化數(shù)據(jù)的傳輸。下面讓我們來看看OAIDL.H文件中VARIANT定義的一個(gè)簡化版:
  struct tagVARIANT {
  VARTYPE vt;
  union {
  short iVal; // VT_I2.
  long lVal; // VT_I4.
  float fltVal; // VT_R4.
  double dblVal; // VT_R8.
  DATE date; // VT_DATE.
  BSTR bstrVal; // VT_BSTR.
  …
  short * piVal; // VT_BYREF|VT_I2.
  long * plVal; // VT_BYREF|VT_I4.
  float * pfltVal; // VT_BYREF|VT_R4.
  double * pdblVal; // VT_BYREF|VT_R8.
  DATE * pdate; // VT_BYREF|VT_DATE.
  BSTR * pbstrVal; // VT_BYREF|VT_BSTR.
  };
  };
  顯然,VARIANT類型是一個(gè)C結(jié)構(gòu),它包含了一個(gè)類型成員vt、一些保留字節(jié)以及一個(gè)大的union類型。例如,如果vt為VT_I2,那么我們可以從iVal中讀出VARIANT的值。同樣,當(dāng)給一個(gè)VARIANT變量賦值時(shí),也要先指明其類型。例如:
  VARIANT va;
  :: VariantInit(&va); // 初始化
  int a = 2002;
  va.vt = VT_I4; // 指明long數(shù)據(jù)類型
  va.lVal = a; // 賦值
  為了方便處理VARIANT類型的變量,Windows還提供了這樣一些非常有用的函數(shù):
  VariantInit —— 將變量初始化為VT_EMPTY;
  VariantClear —— 消除并初始化VARIANT;
  VariantChangeType —— 改變VARIANT的類型;
  VariantCopy —— 釋放與目標(biāo)VARIANT相連的內(nèi)存并復(fù)制源VARIANT。
  COleVariant類是對VARIANT結(jié)構(gòu)的封裝。它的構(gòu)造函數(shù)具有極為強(qiáng)大大的功能,當(dāng)對象構(gòu)造時(shí)首先調(diào)用VariantInit進(jìn)行初始化,然后根據(jù)參數(shù)中的標(biāo)準(zhǔn)類型調(diào)用相應(yīng)的構(gòu)造函數(shù),并使用VariantCopy進(jìn)行轉(zhuǎn)換賦值操作,當(dāng)VARIANT對象不在有效范圍時(shí),它的析構(gòu)函數(shù)就會(huì)被自動(dòng)調(diào)用,由于析構(gòu)函數(shù)調(diào)用了VariantClear,因而相應(yīng)的內(nèi)存就會(huì)被自動(dòng)清除。除此之外,COleVariant的賦值操作符在與VARIANT類型轉(zhuǎn)換中為我們提供極大的方便。例如下面的代碼:
  COleVariant v1("This is a test"); // 直接構(gòu)造
  COleVariant v2 = "This is a test";
  // 結(jié)果是VT_BSTR類型,值為"This is a test"
  COleVariant v3((long)2002);
  COleVariant v4 = (long)2002;
  // 結(jié)果是VT_I4類型,值為2002
  _variant_t是一個(gè)用于COM的VARIANT類,它的功能與COleVariant相似。不過在Visual C++.NET的MFC應(yīng)用程序中使用時(shí)需要在代碼文件前面添加下列兩句:
  #include "comutil.h"
  #pragma comment( lib, "comsupp.lib" )
  四、CComBSTR和_bstr_t
  CComBSTR是對BSTR數(shù)據(jù)類型封裝的一個(gè)ATL類,它的操作比較方便。例如:
  CComBSTR bstr1;
  bstr1 = "Bye"; // 直接賦值
  OLECHAR* str = OLESTR("ta ta"); // 長度為5的寬字符
  CComBSTR bstr2(wcslen(str)); // 定義長度為5
  wcscpy(bstr2.m_str, str); // 將寬字符串復(fù)制到BSTR中
  CComBSTR bstr3(5, OLESTR("Hello World"));
  CComBSTR bstr4(5, "Hello World");
  CComBSTR bstr5(OLESTR("Hey there"));
  CComBSTR bstr6("Hey there");
  CComBSTR bstr7(bstr6);
  // 構(gòu)造時(shí)復(fù)制,內(nèi)容為"Hey there"
  _bstr_t是是C++對BSTR的封裝,它的構(gòu)造和析構(gòu)函數(shù)分別調(diào)用SysAllocString和SysFreeString函數(shù),其他操作是借用BSTR API函數(shù)。與_variant_t相似,使用時(shí)也要添加comutil.h和comsupp.lib。

 

 五、BSTR、char*和CString轉(zhuǎn)換
  (1) char*轉(zhuǎn)換成CString
  若將char*轉(zhuǎn)換成CString,除了直接賦值外,還可使用CString::Format進(jìn)行。例如:
  char chArray[] = "This is a test";
  char * p = "This is a test";
  或
  LPSTR p = "This is a test";
  或在已定義Unicode應(yīng)的用程序中
  TCHAR * p = _T("This is a test");
  或
  LPTSTR p = _T("This is a test");
  CString theString = chArray;
  theString.Format(_T("%s"), chArray);
  theString = p;
  (2) CString轉(zhuǎn)換成char*
  若將CString類轉(zhuǎn)換成char*(LPSTR)類型,常常使用下列三種方法:
  方法一,使用強(qiáng)制轉(zhuǎn)換。例如:
  CString theString( "This is a test" );
  LPTSTR lpsz =(LPTSTR)(LPCTSTR)theString;
  方法二,使用strcpy。例如:
  CString theString( "This is a test" );
  LPTSTR lpsz = new TCHAR[theString.GetLength()+1];
  _tcscpy(lpsz, theString);
  需要說明的是,strcpy(或可移值Unicode/MBCS的_tcscpy)的第二個(gè)參數(shù)是 const wchar_t* (Unicode)或const char* (ANSI),系統(tǒng)編譯器將會(huì)自動(dòng)對其進(jìn)行轉(zhuǎn)換。
  方法三,使用CString::GetBuffer。例如:
  CString s(_T("This is a test "));
  LPTSTR p = s.GetBuffer();
  // 在這里添加使用p的代碼
  if(p != NULL) *p = _T(’\0’);
  s.ReleaseBuffer();
  // 使用完后及時(shí)釋放,以便能使用其它的CString成員函數(shù)
  (3) BSTR轉(zhuǎn)換成char*
  方法一,使用ConvertBSTRToString。例如:
  #include "comutil.h"
  #pragma comment(lib, "comsupp.lib")
  int _tmain(int argc, _TCHAR* argv[]){
  BSTR bstrText = ::SysAllocString(L"Test");
  char* lpszText2 = _com_util::ConvertBSTRToString(bstrText);
  SysFreeString(bstrText); // 用完釋放
  delete[] lpszText2;
  return 0;
  }
  ** 此方法不好,會(huì)造成內(nèi)存泄露,SysFreeString也沒有效果。
  方法二,使用_bstr_t的賦值運(yùn)算符重載。例如:
  _bstr_t b = bstrText;
  char* lpszText2 = b;
  * 不會(huì)有內(nèi)存泄露,推薦方法
  (4) char*轉(zhuǎn)換成BSTR
  方法一,使用SysAllocString等API函數(shù)。例如:
  BSTR bstrText = ::SysAllocString(L"Test");
  BSTR bstrText = ::SysAllocStringLen(L"Test",4);
  BSTR bstrText = ::SysAllocStringByteLen("Test",4);
  方法二,使用COleVariant或_variant_t。例如:
  //COleVariant strVar("This is a test");
  _variant_t strVar("This is a test");
  BSTR bstrText = strVar.bstrVal;
  方法三,使用_bstr_t,這是一種最簡單的方法。例如:
  BSTR bstrText = _bstr_t("This is a test");
  方法四,使用CComBSTR。例如:
  BSTR bstrText = CComBSTR("This is a test");
  或
  CComBSTR bstr("This is a test");
  BSTR bstrText = bstr.m_str;
  方法五,使用ConvertStringToBSTR。例如:
  char* lpszText = "Test";
  BSTR bstrText = _com_util::ConvertStringToBSTR(lpszText);
  (5) CString轉(zhuǎn)換成BSTR
  通常是通過使用CStringT::AllocSysString來實(shí)現(xiàn)。例如:
  CString str("This is a test");
  BSTR bstrText = str.AllocSysString();
  …
  SysFreeString(bstrText); // 用完釋放
  (6) BSTR轉(zhuǎn)換成CString
  一般可按下列方法進(jìn)行:
  BSTR bstrText = ::SysAllocString(L"Test");
  CStringA str;
  str.Empty();
  str = bstrText;
  或
  CStringA str(bstrText);
  (7) ANSI、Unicode和寬字符之間的轉(zhuǎn)換
  方法一,使用MultiByteToWideChar將ANSI字符轉(zhuǎn)換成Unicode字符,使用WideCharToMultiByte將Unicode字符轉(zhuǎn)換成ANSI字符。
  方法二,使用“_T”將ANSI轉(zhuǎn)換成“一般”類型字符串,使用“L”將ANSI轉(zhuǎn)換成Unicode,而在托管C++環(huán)境中還可使用S將ANSI字符串轉(zhuǎn)換成String*對象。例如:
  TCHAR tstr[] = _T("this is a test");
  wchar_t wszStr[] = L"This is a test";
  String* str = S”This is a test”;
  方法三,使用ATL 7.0的轉(zhuǎn)換宏和類。ATL7.0在原有3.0基礎(chǔ)上完善和增加了許多字符串轉(zhuǎn)換宏以及提供相應(yīng)的類。
  其中,第一個(gè)C表示“類”,以便于ATL 3.0宏相區(qū)別,第二個(gè)C表示常量,2表示“to”,EX表示要開辟一定大小的緩沖。SourceType和DestinationType可以是A、T、W和OLE,其含義分別是ANSI、Unicode、“一般”類型和OLE字符串。例如,CA2CT就是將ANSI轉(zhuǎn)換成一般類型的字符串常量。下面是一些示例代碼:
  LPTSTR tstr= CA2TEX<16>("this is a test");
  LPCTSTR tcstr= CA2CT("this is a test");
  wchar_t wszStr[] = L"This is a test";
  char* chstr = CW2A(wszStr);

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    午夜福利精品视频视频| 大香蕉精品视频一区二区| 久久精品中文扫妇内射| 国产精品激情对白一区二区| 日韩欧美三级中文字幕| 国产精品视频久久一区| 亚洲中文字幕在线观看黑人| 91插插插外国一区二区| 黑丝国产精品一区二区| 精品人妻一区二区四区| 国产精品欧美一区二区三区不卡| 九九热精彩视频在线免费| 大胆裸体写真一区二区| 99国产一区在线播放| 亚洲欧美日产综合在线网| 欧美一区二区黑人在线| 99久免费精品视频在线观| 亚洲专区中文字幕在线| 精品一区二区三区乱码中文| 午夜精品麻豆视频91| 日韩中文无线码在线视频| 国产午夜免费在线视频| 这里只有九九热精品视频| 国产精品色热综合在线| 日韩人妻欧美一区二区久久| 亚洲乱妇熟女爽的高潮片| 国产在线小视频你懂的| 欧美日韩精品视频在线| 久久亚洲成熟女人毛片| 国产又色又爽又黄又免费| 日韩欧美第一页在线观看| 国产又色又粗又黄又爽| 很黄很污在线免费观看| 高潮少妇高潮久久精品99| 日本精品啪啪一区二区三区| 丝袜av一区二区三区四区五区| 欧美自拍偷自拍亚洲精品| 久久福利视频在线观看| 国产一区二区三区成人精品| 国产午夜免费在线视频| 国产av一区二区三区久久不卡|