• <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>
            隨筆 - 67  文章 - 171  trackbacks - 0
            <2008年2月>
            272829303112
            3456789
            10111213141516
            17181920212223
            2425262728291
            2345678

            常用鏈接

            留言簿(10)

            隨筆分類

            隨筆檔案

            連接資料

            最新隨筆

            搜索

            •  

            最新隨筆

            最新評論

            一、BSTR、LPSTR和LPWSTR
            在Visual C++.NET的所有編程方式中,我們常常要用到這樣的一些基本字符串類型,如BSTR、LPSTR和LPWSTR等。之所以出現(xiàn)類似上述的這些數(shù)據(jù)類型,是因為不同編程語言之間的數(shù)據(jù)交換以及對ANSI、Unicode和多字節(jié)字符集(MBCS)的支持。

              那么什么是BSTR、LPSTR以及LPWSTR呢?

              BSTR(Basic STRing,Basic字符串)是一個OLECHAR*類型的Unicode字符串。它被描述成一個與自動化相兼容的類型。由于操作系統(tǒng)提供相應(yīng)的API函數(shù)(如SysAllocString)來管理它以及一些默認(rèn)的調(diào)度代碼,因此BSTR實際上就是一個COM字符串,但它卻在自動化技術(shù)以外的多種場合下得到廣泛使用。圖1描述了BSTR的結(jié)構(gòu),其中DWORD值是字符串中實際所占用的字節(jié)數(shù),且它的值是字符串中Unicode字符的兩倍。

              LPSTR和LPWSTR是Win32和VC++所使用的一種字符串?dāng)?shù)據(jù)類型。LPSTR被定義成是一個指向以NULL(‘\0’)結(jié)尾的8位ANSI字符數(shù)組指針,而LPWSTR是一個指向以NULL結(jié)尾的16位雙字節(jié)字符數(shù)組指針。在VC++中,還有類似的字符串類型,如LPTSTR、LPCTSTR等,它們的含義如圖2所示。

              例如,LPCTSTR是指“long pointer to a constant generic string”,表示“一個指向一般字符串常量的長指針類型”,與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中等價于char。wchar_t通常定義為unsigned short。由于CString在MFC應(yīng)用程序中經(jīng)常用到,這里不再重復(fù)。

            三、VARIANT、COleVariant 和_variant_t

              在OLE、ActiveX和COM中,VARIANT數(shù)據(jù)類型提供了一種非常有效的機制,由于它既包含了數(shù)據(jù)本身,也包含了數(shù)據(jù)的類型,因而它可以實現(xiàn)各種不同的自動化數(shù)據(jù)的傳輸。下面讓我們來看看OAIDL.H文件中VARIANT定義的一個簡化版:

            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類型是一個C結(jié)構(gòu),它包含了一個類型成員vt、一些保留字節(jié)以及一個大的union類型。例如,如果vt為VT_I2,那么我們可以從iVal中讀出VARIANT的值。同樣,當(dāng)給一個VARIANT變量賦值時,也要先指明其類型。例如:

            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ù)具有極為強大大的功能,當(dāng)對象構(gòu)造時首先調(diào)用VariantInit進行初始化,然后根據(jù)參數(shù)中的標(biāo)準(zhǔn)類型調(diào)用相應(yīng)的構(gòu)造函數(shù),并使用VariantCopy進行轉(zhuǎn)換賦值操作,當(dāng)VARIANT對象不在有效范圍時,它的析構(gòu)函數(shù)就會被自動調(diào)用,由于析構(gòu)函數(shù)調(diào)用了VariantClear,因而相應(yīng)的內(nèi)存就會被自動清除。除此之外,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是一個用于COM的VARIANT類,它的功能與COleVariant相似。不過在Visual C++.NET的MFC應(yīng)用程序中使用時需要在代碼文件前面添加下列兩句:

              #include "comutil.h"

              #pragma comment( lib, "comsupp.lib" )

            四、CComBSTR和_bstr_t

              CComBSTR是對BSTR數(shù)據(jù)類型封裝的一個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)造時復(fù)制,內(nèi)容為"Hey there"

              _bstr_t是是C++對BSTR的封裝,它的構(gòu)造和析構(gòu)函數(shù)分別調(diào)用SysAllocString和SysFreeString函數(shù),其他操作是借用BSTR API函數(shù)。與_variant_t相似,使用時也要添加comutil.h和comsupp.lib。

            五、BSTR、char*和CString轉(zhuǎn)換

              (1) char*轉(zhuǎn)換成CString

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

            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)類型,常常使用下列三種方法:

              方法一,使用強制轉(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)的第二個參數(shù)是 const wchar_t* (Unicode)或const char* (ANSI),系統(tǒng)編譯器將會自動對其進行轉(zhuǎn)換。

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

            CString s(_T("This is a test "));
            LPTSTR p = s.GetBuffer();
            // 在這里添加使用p的代碼
            if(p != NULL) *p = _T('\0');
            s.ReleaseBuffer();
            // 使用完后及時釋放,以便能使用其它的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;
            }

               ** 此方法不好,會造成內(nèi)存泄露,SysFreeString也沒有效果。

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

            _bstr_t b = bstrText;
            char* lpszText2 = b;   

            * 不會有內(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來實現(xiàn)。例如:

            CString str("This is a test");
            BSTR bstrText = str.AllocSysString();

            SysFreeString(bstrText); // 用完釋放

              (6) BSTR轉(zhuǎn)換成CString

              一般可按下列方法進行:

            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)的類,它具有如圖3所示的統(tǒng)一形式:

              其中,第一個C表示“類”,以便于ATL 3.0宏相區(qū)別,第二個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);

            posted on 2008-08-10 10:26 cpsprogramer 閱讀(19343) 評論(1)  編輯 收藏 引用 所屬分類: VC++
            色欲av伊人久久大香线蕉影院| 久久久久国产精品| 国产—久久香蕉国产线看观看 | 久久国产精品成人免费| 久久亚洲国产精品五月天婷| 思思久久99热只有频精品66| 久久久久久久99精品免费观看| 国产精品久久久天天影视香蕉| 亚洲国产成人精品91久久久 | 精品久久久久久综合日本| 超级碰久久免费公开视频| 久久99九九国产免费看小说| 国产精品视频久久| 青草国产精品久久久久久| 91精品国产综合久久香蕉| 欧美噜噜久久久XXX| 欧美大战日韩91综合一区婷婷久久青草| A级毛片无码久久精品免费| 久久久久亚洲AV成人网人人软件| 国产精品久久久久国产A级| 囯产极品美女高潮无套久久久 | 久久亚洲精精品中文字幕| 久久久中文字幕日本| 久久99国产精品久久久| 亚洲国产精品无码成人片久久| 久久WWW免费人成—看片| 久久精品国产福利国产秒| 成人午夜精品无码区久久 | 久久久久人妻一区二区三区 | 四虎国产精品免费久久5151 | 久久国产欧美日韩精品| 久久久久亚洲精品男人的天堂| 精品久久久久久亚洲| 久久ZYZ资源站无码中文动漫 | 免费无码国产欧美久久18| 久久精品国产亚洲Aⅴ蜜臀色欲| 99热成人精品免费久久| 久久亚洲国产中v天仙www| 亚洲国产精品热久久| 国产999精品久久久久久| 国产欧美久久久精品|