카페 >
프로그래머들의 세계 |
필더
http://cafe.naver.com/programmers/649
It is a 16-bit Unicode with a prefix telling the count of the bytes in this string, therefore do not need NULL at the end.
When a server creates and passes out a BSTR, the server allocates memory space for the BSTR,
Because one convertion involves a series of temporary variables to hold and swap the string buffers,
MFC provides class _bstr_t to wrap BSTR.
_bstr_t's constructor can take many types as input:
To get a LPTSTR from _bstr_t:
You can use _bstr_t anywhere expecting BSTR.
If you like, you can also explicitly cast _bstr_t to BSTR:
It is deallocated automatically when it leaves scope.
Class _bstr_t is contained in header file <comdef.h>.
ATL also provides a wrapper class CComBSTR, which is more light than _bstr_t.
CComBSTR wraps a BSTR data member m_str.
Space for BSTR is allocated in its constructor and dealocated in the destructor.
Its constructor can take LPCOLESTR or LPCSTR as input.
It can also designate the size of the buffer.
http://progtutorials.tripod.com/COM.htm
http://cafe.naver.com/programmers/649
문자열 다루기
STL의 string을 사용
#include <TCHAR.h>
#include <string>
namespace std { typedef basic_string<TCHAR> tstring; }
To be continued...static 함수 및 버퍼 사용
/**
* Maps a character string to a wide-character (Unicode) string.
* @param[in] lpsz ASCII string
* @return UNICODE string
*/
static WCHAR* ToWChar(LPCSTR* lpsz)
{
static WCHAR wszBuffer[1024];
_wcsset(wszBuffer, 0);
int nWStrLen = /* the number of wide characters written to the buffer */
MultiByteToWideChar(
CP_ACP, /* CodePage: ANSI code page */
0, /* dwFlags: character-type options */
lpsz, /* lpMultiByteStr: string to map */
-1, /* cbMultiByte: number of bytes in string */
wszBuffer, /* lpWideCharStr: wide-character buffer */
1024); /* cchWideChar: size of buffer */
return wszBuffer;
}
MultiByteToWideChar function- If cbMultiByte equals -1,
the function processes the entire input string including the null terminator.
The resulting wide character string therefore has a null terminator, and the returned length includes the null terminator. - If the function succeeds, and cchWideChar is nonzero,
the return value is the number of wide characters written to the buffer pointed to by lpWideCharStr. - If the function succeeds, and cchWideChar is zero,
the return value is the required size, in wide characters, for a buffer that can receive the translated string. - If dwFlag equals zero, the input string is UTF-8 and contains invalid characters
the function returns ERROR_NO_UNICODE_TRANSLATION. - If the function fails, the return value is zero.
To get extended error information, call GetLastError.
GetLastError may return one of the following error codes:
- ERROR_INSUFFICIENT_BUFFER
- ERROR_INVALID_FLAGS
- ERROR_INVALID_PARAMETER
- ERROR_NO_UNICODE_TRANSLATION
/**
* Maps a wide-character string to a character string.
* @param[in] lpwsz UNICODE string
* @return ASCII string
*/
static LPSTR ToAChar(const WCHAR* lpwsz)
{
static char szBuffer[1024];
_strset(szBuffer, 0);
int nAStrLen = /* the number of bytes written to the buffer. */
WideCharToMultiByte(
CP_ACP, /* CodePage: ANSI code page */
0, /* dwFlags: performance and mapping flags */
lpwsz, /* lpWideCharStr: wide-character string */
-1, /* cchWideChar: number of chars in string */
szBuffer, /* lpMultiByteStr: buffer for new string */
1024, /* cbMultiByte: size of buffer */
NULL, /* lpDefaultChar: default for unmappable chars */
NULL); /* lpUsedDefaultChar: set when default char used */
return szBuffer;
}
- WideCharToMultiByte function
- If cchWideChar equals -1,
the string is assumed to be null-terminated and the length is calculated automatically.
The length will include the null-terminator. - If the function succeeds, and cbMultiByte is nonzero,
the return value is the number of bytes written to the buffer pointed to by lpMultiByteStr.
The number includes the byte for the null terminator. - If the function succeeds, and cbMultiByte is zero,
the return value is the required size, in bytes, for a buffer that can receive the translated string. - If the function fails, the return value is zero.
To get extended error information, call GetLastError.
GetLastError may return one of the follwing error codes:
- ERROR_INSUFFICIENT_BUFFER
- ERROR_INVALID_FLAGS
- ERROR_INVALID_PARAMETER
- If cchWideChar equals -1,
In GDI+, all the parameters about the symbol are WCHAR type.
Examples
char szSrc[] = "유니코드 변환 예제";
BSTR wsDst; /* 유니코드 변수 */
;
int nSrcLen = strlen(szSrc);
int nDstLen = MultiByteToWideChar(CP_ACP, 0, szSrc, nSrcLen, NULL, NULL);
wsDst = (BSTR)SysAllocStringLen(NULL, nDstLen);
MultiByteToWideChar(CP_ACP, 0, szSrc, nSrcLen, wsDst, nDstLen);
;
SysFreeString(wsDst);
- MultiByteToWideChar function
- If cchWideChar equals zero,
the function returns the required buffer size, in wide charcters,
and makes no use of the lpWideCharStr buffer. - If the function succeeds, and cchWideChar is zero,
the return value is the required size, in wide characters, for a buffer that can receive the translated string.
- If cchWideChar equals zero,
BSTR wsSrc = L"아스키코드로 변환 예제";
char* szDst = NULL;
;
int nDstLen = WideCharToMultiByte(CP_ACP, 0, wsSrc, -1, szDst, 0, NULL, NULL);
szDst = new char[nDstLen + 1];
WideCharToMultiByte(CP_ACP, 0, wsSrc, -1, szDst, ,NULL, NULL);
;
delete [] szDst;
- WideCharToMultiByte function
- If cbMultiByte equals zero,
the function returns the number of bytes required for the buffer.
In this case, the lpMultiByteStr buffer is not used. - If the function succeeds, and cbMultiByte is zero,
the return value is the required size, in bytes, for a buffer that can receive the translated string.
- If cbMultiByte equals zero,
ANSI to UTF-8
char* pszANSI = "ANSI string";
int nAStrLen, nBStrLen, nU8StrLen;
BSTR bstr;
char* pszUTF8 = NULL;
;
nAStrLen = lstrlen(pszANSI);
nBStrLen = MultiByteToWideChar(CP_ACP, 0, pszANSI, nAStrLen, NULL, NULL);
bstr = SysAllocStringLen(NULL, nBStrLen);
MultiByteToWideChar(CP_ACP, 0, pszANSI, nAStrLen, bstr, nBStrLen);
;
nU8StrLen = WideCharToMultiByte(CP_UTF8, 0, bstr, -1, pszUTF8, 0, NULL, NULL);
pszUTF8 = new char[nU8StrLen + 1];
WideCharToMultiByte(CP_UTF8, 0, bstr, -1, pszUTF8, nU8StrLen, NULL, NULL);
SysFreeString(bstr);
;
delete [] pszUTF8;
UTF-8 to ANSI
char* pszUTF8; /* UTF-8 string */
int nU8StrLen, nBStrLen, nAStrLen;
BSTR bstr;
char* pszANSI;
;
nU8StrLen = lstrlen(pszUTF8);
nBStrLen = MultiByteToWideChar(CP_UTF8, 0, pszUTF8, nU8StrLen + 1, NULL, NULL);
bstr = SysAllocStringLen(NULL, nBStrLen);
MultiByteToWideChar(CP_UTF8, 0, pszUTF8, nU8StrLen + 1, bstr, nBStrLen);
;
nAStrLen = WideCharToMultiByte(CP_ACP, 0, bstr, -1, NULL, 0, NULL, NULL);
pszANSI = new char[nAStrLen];
WideCharToMultiByte(CP_ACP, 0, bstr, -1, pszANSI, nAStrLen, NULL, NULL);
SysFreeString(bstr);
;
delete [] pszANSI;
Definitions of Different Type of Strings
/* 16-bit wide(UNICODE) character */
typedef unsigned short wchar_t
typedef wchar_t WCHAR;
/* 16-bit UNICODE string */
typedef WCHAR OLECHAR;
typedef OLECHAR _RPC_FAR *LPOLESTR;
typedef const OLECHAR __RPC_FAR *LPCOLESTR;
/* 8-bit multi-byte/ANSI string */
typedef char CHAR;
typedef CHAR *LPSTR, *PSTR;
typedef const CHAR *LPCSTR, *PCSTR;
typedef char TCHAR, *PTCHAR;
CString <=> Multibyte String
int test_str(LPCTSTR lpStr);
CString cstr("dozob's knowledge note");
/* CString::GetBuffer returns a pointer to its underlying buffer. */
LPSTR lpsz = cstr.GetBuffer(cstr.GetLength());
/* Both cstr and lpsz can access the underlying buffer. */
test_str(cstr);
test_str(lpsz);
/* You can amend the buffer through cstr. */
cstr = "01234567";
test_str(lpsz);
/* You can also amend the buffer through lpsz, but you cannot free it. */
lpsz[8] = '!';
test_str(cstr);
// free(lpsz); /* Not allowed! Will cause run-time error! */
/* After releasing the buffer, lpsz's content becomes undefined. */
cstr.ReleaseBuffer();
test_str(cstr);
/* If you want to avoid amending the original content of the CString, make a copy. */
LPSTR lpszCopy = (LPSTR)malloc(strlen(lpsz));
memset(lpszCopy, 0, strlen(lpsz) + 1);
strcopy(lpszCopy, lpsz);
test_str(lpszCopy);
CString <=> Wide Character String
void CStringToWideChar(CString cstr, wchar_t* pwchar, int size)
{
int cstrLen = cstr.GetLength();
ASSERT( cstrLen < MAX_LENGTH );
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,
cstr.GetBuffer(cstrLen), cstrLen, pwchar, size);
cstr.ReleaseBuffer();
}
Allocating and Freeing BSTRs with API Functions
BSTR stands for basic string.It is a 16-bit Unicode with a prefix telling the count of the bytes in this string, therefore do not need NULL at the end.
When a server creates and passes out a BSTR, the server allocates memory space for the BSTR,
while the client should deallocate the memory with a call to API function SysFreeString.
- Creating a new BSTR
BSTR bstr1 = SysAllocString(L"BSTR string");
OLECHAR* pOleStr = OLESTR("OLE string");
BSTR bstr2 = SysAllocString(pOleStr);
Modifying a BSTRSysReAllocString(&bstr1, L"new BSTR string");
Freeing a BSTR
SysFreeString(bstr1);
SysFreeString(bstr2);
BSTR <=> CString
CString cstr("MFC String");
BSTR bstr = cstr.AllocSysString();
BSTR bstr = SysAllocString(L"BSTR string");
CString cstr(bstr);
BSTR <=> Multibyte String
BSTR bstr = SysAllocString(L"BSTR string");
char szBuffer[80];
/* wide character string to multibyte string */
wcstombs(szBuffer, bstr, 80);
SysFreeString(bstr);
sprintf(szBuffer, "Multibyte string");
/* multibyte string to wide character string */
mbstowcs(bstr, szBuffer, 80);
Multibyte String <=> Wide Character String
char* mbstr = "multibyte string";
;
wchar_t wcBuffer[80];
int mbsLen = strlen(mbstr);
int wcsLen = sizeof(wcBuffer) / sizeof(wchar_t);
::memset(wcBuffer, 0, sizeof(wcBuffer));
/* dwFlag = MB_PRECOMPOSED
* Always use precomposed characters that is, characters
* in which a base character and a nonspacing character have a single character value.
* This is the default translation option.
*/
MultiByteToWideChar(
CP_ACP, MB_PRECOMPOSED,
mbstr, mbsLen,
wcBuffer, wcsLen);
;
char szBuffer[256];
/* Type Field Character: S
* specifies a wide-character string;
*/
sprintf(szBuffer, "wcBuffer = %S", wcBuffer);
::MessageBox(NULL, szBuffer, NULL, MB_OK);
wchar_t wcstr = L"wide character string";
wcsLen = wcslen(wcstr);
;
char mbBuffer[256];
mbsLen = sizeof(mbBuffer);
::memset(mbBuffer, 0, mbsLen);
/* dwFlags = WC_COMPOSITECHECK
* Convert composite characters to precomposited characters.
*/
WideCharToMultiByte(
CP_ACP, WC_COMPOSITECHECK,
wcstr, wcsLen,
mbBuffer, mbsLen,
NULL, NULL);
::MessageBox(NULL, mbBuffer, NULL, MB_OK);
Converting with ATL Macros
ATL provides a group of macros to convert between different types.Because one convertion involves a series of temporary variables to hold and swap the string buffers,
the space is prepared by macro USES_CONVERSION, which should be called before any conversion.
They are defined in <atlconv.h>.ANSI to ... | OLE to ... | WCHAR to ... | TCHAR to ... | |
---|---|---|---|---|
ANSI | OLE2A | W2A | T2A | |
cosnt ANSI | OLE2CA | W2CA | T2CA | |
OLE | A2OLE | W2OLE | T2OL | |
const OLE | A2COLE | W2COLE | T2COLE | |
WCHAR | A2W | OLE2W | T2W | |
const WCHAR | A2CW | OLE2CW | T2CW | |
TCHAR | A2W | OLE2T | W2T | |
const TCHAR | A2CW | OLE2CT | W2CT | |
BSTR | A2BSTR | OLE2BSTR | W2BSTR | T2BSTR |
- USES_ONVERSION;
- ::MessageBox(NULL, W2A(bstr), NULL, MB_OK);
MFC's BSTR Helper Class _bstr_t
MFC provides class _bstr_t to wrap BSTR.
_bstr_t's constructor can take many types as input:
- _bstr_t() throw();
- _bstr_t(const _bstr_t& s1) throw();
- _bstr_t(const char* s2) throw(_com_error);
- ;
- ...
To get a LPTSTR from _bstr_t:
- _bstr_t bstrt("bstr_t string");
- LPTSTR lptstr = (LPTSTR)bstrt;
You can use _bstr_t anywhere expecting BSTR.
If you like, you can also explicitly cast _bstr_t to BSTR:
- _bstr_t bstrt("bstr_t string");
- BSTR bstr = (BSTR)bstrt;
- SysFreeString(bstr);
It is deallocated automatically when it leaves scope.
Class _bstr_t is contained in header file <comdef.h>.
ATL's BSTR Helper Class CComBSTR
ATL also provides a wrapper class CComBSTR, which is more light than _bstr_t.
CComBSTR wraps a BSTR data member m_str.
Space for BSTR is allocated in its constructor and dealocated in the destructor.
Its constructor can take LPCOLESTR or LPCSTR as input.
It can also designate the size of the buffer.
CComBSTR(int nSize);
CComBSTR(int nSize, LPCOLESTR sz);
CComBSTR(int nSize, LPCSTR sz);
CComBSTR(LPCOLESTR pSrc);
CComBSTR(LPCSTR pSrc);
CComBSTR(const CComBSTR& src);
BSTR bstr = SysAllocString(L"BSTR string");
CComBSTR comBstr;
/* attach a BSTR to a CComBSTR */
comBstr.Attatch(bstr);
/* detach m_str from CComBSTR */
bstr = comBstr.Detach();
CComBSTR comBstr = L"CComBSTR string";
/* get a copy of m_str */
BSTR bstrCopy = comBstr.Copy();
/* get the address of m_str */
BSTR* pBstr = &comBstr;
/* free m_str */
comBstr.Empty();
CComBSTR comBstr = L"CComBSTR string";
/* CComBSTR can only be casted to CString,
* which can be than casted to LPCSTR or LPCTSTR.
*/
CString cstr = (CString)comBstr;
CComBSTR is contained in header file <atlbase.h>, which also contains other wraper clases.Reference sites
http://progtutorials.tripod.com/COM.htm
gicomAinchi Marcos Lassiter click
답글삭제goorumetal