青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

Hello World!

程序員那點事兒

首頁 新隨筆 聯系 聚合 管理
  20 Posts :: 6 Stories :: 0 Comments :: 0 Trackbacks
概述
  它被描述成一個與自動化相兼容的類型,由于操作系統提供相應的API函數(如SysAllocString)來管理它以及一些默認的調度代碼。因此BSTR實際上就是一個COM字符串,但它卻在自動化技術以外的多種場合下得到廣泛使用。

為什么需要BSTR

  COM是一種跨編程語言的平臺,需要提供語言無關的數據類型。多數編程語言有自己的字符串表示。
  ●C++ 字符串是以0結束的ASCII或Unicode字符數組。
  ●Visual Basic字符串是一個ASCII字符數組加上表示長度的前綴。
  ●Java字符串是以0結束的Unicode字符數組。
  需要定義一種通用的字符串類型,可以很容易的匹配到不同編程語言。C++中,就是BSTR

什么是BSTR

  BSTR是“Basic STRing”的簡稱,微軟在COM/OLE中定義的標準字符串數據類型。
  對于C++,Windows頭文件wtypes.h中定義如下:
  typedef wchar_t WCHAR;
  typedef WCHAR OLECHAR;
  typedef OLECHAR __RPC_FAR *BSTR;;
  使用以Null結尾的簡單字符串在COM component間傳遞不太方便。因此,標準BSTR是一個有長度前綴和null結束符的OLECHAR數組。BSTR的前4字節是一個表示字符串長度的前綴。BSTR長度域的值是字符串的字節數,并且不包括0結束符。
  由于是Unicode串,所以字符數是字節數的一半。這種方式的優點是允許程序員在BSTR串中間嵌入NULL字符。但是,BSTR的前四個字節表示長度,而OLECHAR數組的前四字節表示前兩個字符。這種情況下,對于C++程序,如何實現BSTR和OLECHAR的交換?答案是COM提供了兩個BSTR分配用的API:SysAllocString / SysReallocString。函數返回的指針指向BSTR的第一個字符,而不是BSTR在內存的第一個字節。

什么時候使用BSTR

  只有在你不得不用的時候。
  使用BSTR一般有以下幾種情況:
  ●COM interface接口定義,并且不希望額外提供custom marshaling庫(MDIL生成或開發人員自己訂制),必須使用BSTR傳遞字符串。使用C/C++類型的字符串在COM DLL傳遞字符串,表面上可以使用,但違背了COM的基本規則,并且給以后的擴展留下了隱患。例如,把一個In-process COM Object(簡單說COM DLL)改成out-of-process object(COM EXE)。理論上,客戶端的代碼應該不做任何改變。但如果是用了C/C++字符串,又希望只使用系統的automation mashaller(Oleaut32.dll),就會出錯。
  ●如果可以提供custom marshaling,也推薦使用BSTR。
  ●客戶要求接口必須使用BSTR,和客戶討論后,不能修改。
  ●使用的外部庫的接口使用BSTR
  不使用的情況:
  ●不推薦在IDL結構體中定義BSTR成員,會給結構體的復制和釋放帶來麻煩。最好直接使用限定最大長度的TCHAR數組。如果確實需要傳遞變長字符串,BSTR應該被定義成獨立的參數或者使用獨立的get/set接口。
  ●盡可能縮小的BSTR及相關類型的作用域范圍。類的成員變量和函數參數不使用BSTR。局部變量要盡快釋放類的內部不使用BSTR。代碼處理邏輯中只在接口直接相關部分使用BSTR。接收到一個BSTR時,盡量立刻變成C/C++的字符串副本進行處理。在需要傳遞BSTR參數前產生BSTR,用過立即釋放。

BSTR、char*和CString轉換 
  (1) char*轉換成CString

  若將char*轉換成CString,除了直接賦值外,還可使用CString::Format進行。例如:

char chArray[] = "This is a test"; 
char * p = "This is a test"; 

  或

LPSTR p = "This is a test"; 

  或在已定義Unicode應的用程序中

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轉換成char*

  若將CString類轉換成char*(LPSTR)類型,常常使用下列三種方法:

  方法一,使用強制轉換。例如:

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)的第二個參數是 const wchar_t* (Unicode)或const char* (ANSI),系統編譯器將會自動對其進行轉換。

  方法三,使用CString::GetBuffer。例如:

CString s(_T("This is a test ")); 
LPTSTR p = s.GetBuffer(); 
// 在這里添加使用p的代碼 
if(p != NULL) *p = _T('\0'); 
s.ReleaseBuffer(); 
// 使用完后及時釋放,以便能使用其它的CString成員函數 

  (3) BSTR轉換成char*

  方法一,使用ConvertBSTRToString。例如:

#include 
#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; 
}  

  方法二,使用_bstr_t的賦值運算符重載。例如:

_bstr_t b = bstrText; 
char* lpszText2 = b; 

  (4) char*轉換成BSTR

  方法一,使用SysAllocString等API函數。例如:

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轉換成BSTR

  通常是通過使用CStringT::AllocSysString來實現。例如:

CString str("This is a test"); 
BSTR bstrText = str.AllocSysString(); 
… 
SysFreeString(bstrText); // 用完釋放  

  (6) BSTR轉換成CString

  一般可按下列方法進行:

BSTR bstrText = ::SysAllocString(L"Test"); 
CStringA str; 
str.Empty(); 
str = bstrText;  

  或

CStringA str(bstrText); 

  (7) ANSI、Unicode和寬字符之間的轉換

  方法一,使用MultiByteToWideChar將ANSI字符轉換成Unicode字符,使用WideCharToMultiByte將Unicode字符轉換成ANSI字符。

  方法二,使用“_T”將ANSI轉換成“一般”類型字符串,使用“L”將ANSI轉換成Unicode,而在托管C++環境中還可使用S將ANSI字符串轉換成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的轉換宏和類。ATL7.0在原有3.0基礎上完善和增加了許多字符串轉換宏以及提供相應的類,它具有如圖3所示的統一形式:

  其中,第一個C表示“類”,以便于ATL 3.0宏相區別,第二個C表示常量,2表示“to”,EX表示要開辟一定大小的緩沖。SourceType和DestinationType可以是A、T、W和OLE,其含義分別是ANSI、Unicode、“一般”類型和OLE字符串。例如,CA2CT就是將ANSI轉換成一般類型的字符串常量。下面是一些示例代碼:

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);  

  六、結語

  幾乎所有的程序都要用到字符串,而Visual C++.NET由于功能強大、應用廣泛,因而字符串之間的轉換更為頻繁。本文幾乎涉及到目前的所有轉換方法。當然對于.NET框架來說,還可使用Convert和Text類進行不同數據類型以及字符編碼之間的相互轉換。
 
posted on 2012-03-28 10:52 hello wold! 閱讀(19845) 評論(0)  編輯 收藏 引用 所屬分類: 技術相關
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美大片一区二区三区| 在线观看不卡| 欧美日韩一二三区| 亚洲国产高清高潮精品美女| 99re热这里只有精品视频| 亚洲欧美制服另类日韩| 久久久久久亚洲精品杨幂换脸| 欧美精品导航| 欧美激情第三页| 黄色成人av| 久久亚洲图片| 99视频一区二区三区| 新狼窝色av性久久久久久| 欧美视频在线观看| 久久一区二区三区四区| 久久久久久一区| 亚洲欧洲综合另类在线| 伊人蜜桃色噜噜激情综合| 怡红院精品视频在线观看极品| 在线观看亚洲a| 一本色道久久88综合日韩精品| 欧美视频1区| 国产精品―色哟哟| 欧美日韩美女在线| 国产欧美一区二区精品性| 免费视频最近日韩| 亚洲午夜视频| 亚洲日本中文字幕| 亚洲欧美国产毛片在线| 亚洲免费精彩视频| 欧美激情一区二区| 亚洲人成小说网站色在线| 亚洲一区免费视频| 亚洲午夜久久久久久久久电影院| 99热在这里有精品免费| 亚洲欧美一区二区在线观看| 久久久久在线观看| 国产精品麻豆欧美日韩ww| 欧美风情在线观看| 欧美一区二区三区播放老司机| 一区二区三区欧美在线观看| 暖暖成人免费视频| 久久裸体艺术| 一区二区三区www| 老鸭窝91久久精品色噜噜导演| 性欧美18~19sex高清播放| 亚洲精品女av网站| 久久综合狠狠综合久久综合88| 欧美在线黄色| 精品二区视频| 国产一区二区三区四区| 国产精品高潮视频| 欧美日韩精品免费观看| 老司机免费视频一区二区| 国产精品女主播在线观看| 亚洲日本成人| 国产精品成人一区二区三区吃奶| 伊人久久成人| 久久精品国语| 欧美国产亚洲另类动漫| 欧美一区二区三区免费视| 国产精品va在线| 国产精品高清一区二区三区| 在线日韩欧美| 亚洲高清在线精品| 亚洲一区三区视频在线观看| 可以免费看不卡的av网站| 精东粉嫩av免费一区二区三区| 欧美一区国产在线| 欧美亚洲一区二区在线| 国产精自产拍久久久久久| 国产欧美一区二区三区在线老狼| 中日韩美女免费视频网址在线观看| 一区二区三区视频在线播放| 亚洲特色特黄| 亚洲一级黄色| 国产一区二区高清不卡| 欧美主播一区二区三区美女 久久精品人| 亚洲免费福利视频| 欧美丝袜第一区| 欧美在线啊v| 久久成年人视频| 欧美另类综合| 国产精品久久网站| 午夜精品国产| 欧美激情中文字幕一区二区| 麻豆精品在线播放| 国产精品老牛| 亚洲综合大片69999| 久久经典综合| 久久精品日韩欧美| 欧美日韩免费精品| 亚洲欧洲av一区二区| 亚洲一级二级在线| 在线日韩av片| 日韩一级大片| 国精品一区二区| 精品成人国产| 最新精品在线| 国产亚洲欧美另类中文| 久久资源在线| 欧美视频你懂的| 久久亚洲国产成人| 欧美婷婷在线| 麻豆精品国产91久久久久久| 99视频有精品| 欧美18av| 久久国产精品久久精品国产 | 亚洲欧洲在线一区| 亚洲小视频在线观看| 国产有码一区二区| 中文av一区二区| 欧美插天视频在线播放| 亚洲男人影院| 一区二区高清视频在线观看| 韩国成人理伦片免费播放| 亚洲精品国产无天堂网2021| 国产精品免费一区二区三区观看| 欧美大片免费观看| 久久久久久夜| 亚洲欧美日本日韩| 欧美片第一页| 欧美激情按摩在线| 极品少妇一区二区三区精品视频| 亚洲国产日韩欧美| 久久精品午夜| 亚洲综合999| 欧美视频不卡| 99精品视频一区二区三区| 亚洲福利视频三区| 亚洲欧美日韩国产一区二区三区| 国产精品99久久久久久有的能看| 麻豆成人在线播放| 麻豆精品在线视频| 国产视频在线观看一区| 午夜精品久久99蜜桃的功能介绍| 久久视频国产精品免费视频在线 | 美女成人午夜| 老色鬼久久亚洲一区二区| 久久久在线视频| 国产一区二区三区在线免费观看 | 欧美福利在线观看| 欧美激情1区2区| 狠狠色香婷婷久久亚洲精品| 亚洲在线免费视频| 亚洲图色在线| 国产精品乱人伦一区二区| 日韩一本二本av| 午夜精品在线| 红桃视频成人| 欧美伊人久久久久久午夜久久久久| 国产一区在线视频| 久久国产免费| 欧美18av| 一区二区三区日韩精品| 国产精品毛片在线看| 亚洲综合视频在线| 久久久xxx| 欧美黄色日本| 亚洲精品视频免费在线观看| 亚洲无吗在线| 老牛国产精品一区的观看方式| 久久综合激情| 日韩亚洲成人av在线| 国产精品久久久久久久第一福利| 午夜精品久久久久99热蜜桃导演| 久久裸体艺术| 亚洲精品日韩久久| 欧美午夜久久久| 性欧美长视频| 欧美激情在线有限公司| 一区二区日韩| 国产自产精品| 欧美日韩成人综合在线一区二区| 亚洲影音先锋| 母乳一区在线观看| 亚洲一区二区三区四区在线观看 | 亚洲欧洲另类国产综合| 亚洲图片欧美一区| 亚洲高清在线| 国产农村妇女毛片精品久久麻豆| 久久精品在线免费观看| 99ri日韩精品视频| 开心色5月久久精品| 一区二区三区**美女毛片| 国产欧美日韩一区二区三区| 欧美成人官网二区| 欧美一区深夜视频| 一区二区三区高清| 亚洲大胆在线| 久久精品一二三区| 亚洲一区二区精品| 一区二区三区亚洲| 国产日韩视频| 欧美性色视频在线| 欧美日韩岛国| 欧美激情第3页| 久久蜜桃av一区精品变态类天堂| 一区二区毛片| 亚洲精品资源美女情侣酒店|