천객만래 [千客萬來] (It has an interminable succession of visitors)

LPSTR LPCTSTR 위험 CStrgin -> char 으로 변환




(LPSTR)(LPCTSTR)csTest은 위험하다.!!
-. 유니코드를 고려하지 않았을뿐 아니라
-. 위험하게 내부데이터를 접근합니다.
 
CString strPP;
char * chNN = (LPSTR)(LPCSTR)strPP;
이렇게 해서 chNN을 CString의 포인터로 가져 옵니다.

(LPSTR)(LPCSTR)strPP 이 부분 에서 이유는 MSDN을 찾아보시면 아시겠지만 CString은 const char * 으로 만 받을수 있답니다. 
그래서 (LPCTSTR)strPP 이런 형식으로도 사용합니다. 물론 const char *으로 return되겠죠.. 다시 char *을 필요하신다면  
char * chNN = (char *)(LPCTSTR)strPP; 이런 식으로도 사용합니다
 
char *pstr = (LPSTR)(LPCTSTR)str;        이 줄은 UNICODE인경우 
    char *pstr = (char *) (const wchar_t *) str;    입니다.
특히 wchar_t를 본래데이터형으로 보지 않을 경우
    char *pstr = (char *)(const unsigned short *)str;   입니다..
 
유니코드를 고려하지 않는다고 하더라도, CString이 제공하는 것은 const 가 붙은 형변환 밖에 없는데,
이걸 const 를 억지로 빼버리고는 마치 접근해서 고쳐도 되는 것처럼 보이게 되므로 
잘못사용하면 오류를 일으키며. 프로그램이 뻗을수도 있습니다.
 
const 변환은 받는 쪽에서 안고친다고 보고 CString이 자기 내부 메모리주소를 살짝 보여주는 건데.. 
그걸 char로 바꾸고 쓰려고 하면 당연히 에러가 발생 하겠죠...
보통 이런 문제는 char[50] 에서 처럼 .. "특정 위치의 글자를 바로 접근할 수 있냐..?"란 의문에서 생기는데 
이 문제는 CString만으로도 충분합니다.

CString이 operator[] 를 제공하고 있습니다.. operator를 이용 하면 됩니다.. 
str[23] 이렇게 마치 char[] 처럼 사용하실수 있습니다. 
물론 이때도 배열의 길이를 넘어서는 접근은 피해야 합니다.
C/C++의 배열이 제공못하는 길이를 CString은 GetLength()형태로 제공하니 얼마나 편합니까 .
출처:이상 데브피아
 
 
"이하" 파란 생각~
CString csTest = "사나이로 태어나서 할일은 사랑하기";
char* cTest = (LPSTR)(LPCTSTR)csTest;
AfxMessageBox(cTest);
 
즉, 위와 같이 무리한 형변환 보다는 CString의 Operator의 GetBuffer()을 사용해서 가지고오면 더욱 효율적입니다.
char* cTest;
CString csTest = "사나이로 태어나서 할일은 사랑하기";
cTest = csTest.GetBuffer(0);                //GetBuffer(0): csTest가 가지고 있는 문자열의 만큼 가지고 온다는 의미
AfxMessageBox(cTest);
 







Posted by SB패밀리


문자관련 함수

MBCS(multi-byte character set) : ASCII 코드 문자열을 쓰는 함수
WCS(wide character string) : 유니코드 문자열을 쓰는 함수

함수 제일 뒤에 ASCII를 나타내는 A와 Wide Character를 나타내는 W를 붙여서 구분함.
예)  GetCurrentDirectoryA ...
예외) cout, wcout

LPCTSTR(Long Pointer Constant TCHAR String)
여기서 TCHAR 라는 것은 typedef  유니코드가 설정되어 있으면 2바이트로(wchar_t) 아니면 기존 char 방식인 1바이트로(char) 한다는 것을 의미.

LPSTR : 8비트 윈도우 캐릭터 스트링(string) 포인터 문자.
LPCSTR : LPSTR 와 같고 단지 상수형(Constant )이라는 포인터문자.

참조:
http://cafe.naver.com/whatvoip.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=225


--> MFC의 CString 은 TCHAR 형이다.

ATL 형변환 메크로

종류는 [소스 타입]2[새로운 타입][소스 타입]2C[새로운 타입] 이 있다.
여기서 2C의 C는 const형(읽기전용)이라는 뜻이다.

ATL 3.0 String Conversion Macros

A2BSTR OLE2A T2A W2A
A2COLE OLE2BSTR T2BSTR W2BSTR
A2CT OLE2CA T2CA W2CA
A2CW OLE2CT T2COLE W2COLE
A2OLE OLE2CW T2CW W2CT
A2T OLE2T T2OLE W2OLE
A2W OLE2W T2W W2T



여기서 A, W, T, OLE, BSTR이 있는데 그 의미는 다음과 같다.

A : MBCS 스트링, char* (A 는 ANSI를 의미) -> LPSTR
W : Unicode 스트링, wchar_t* (W는 wide를 의미) -> LPWSTR
T : TCHAR 스트링, TCHAR* -> LPTSTR
OLE : OLECHAR 스트링, OLECHAR* (사실, W와 같은 의미) -> LPOLESTR
BSTR : BSTR

이를 통해 몇가지 메크로를 분석해 보면

매크로 인자 결과
A2CW (LPCSTR) (LPCWSTR)
A2W (LPCSTR) (LPWSTR)
W2CA (LPCWSTR) (LPCSTR)
W2A (LPCWSTR) (LPSTR)
T2COLE (LPCTSTR) (LPCOLESTR)
T2OLE (LPCTSTR) (LPOLESTR)
OLE2CT (LPCOLESTR) (LPCTSTR)
OLE2T (LPCOLESTR) (LPCSTR)



*사용법:
#include <atlconv.h>
void func( LPSTR lpsz )
{
   USES_CONVERSION; //형변환 메크로를 사용하기 위해서.
   ...
   LPWSTR x = A2W(lpsz)
   // Do something with x
   ...
}

*사용시 주의점:
이 매크로는 메모리를 스택에 잡음:
1) 과도한 순환문 속에서는 사용하면 안됨.
   - 매크로가 불릴 때마다 스택의 메모리를 잡아먹습니다.
   - 그 메모리는 함수가 끝날 때까지 해제되지 않습니다.
2) 매크로의 결과를 리턴하면 안됨.
   - 결과로 나오는 포인터는 함수가 끝날 때까지만 유효합니다.

참조 :
http://msdn.microsoft.com/en-us/library/87zae4a3(VS.80).aspx
http://jof4002.net/?Unicode
http://eroom.korea.com/post/board.aspx?bid=kmh_19505&mode=read&view=board&pid=189103&page=1


LPWSTR to CString

(CString) 으로 캐스팅하면 끝


CString to LPWSTR

CString strString = "abcd";
BSTR bstrString = strString.AllocSysString();
LPWSTR pwstr = (LPWSTR)bstrString;
SysFreeString(bstrString);

CString to LPTSTR

CString str = _T("new text");

  LVITEM item = {0};
 
  item.mask = LVIF_TEXT;
  item.iItem = 1;
  item.pszText = (LPTSTR)(LPCTSTR) str; // 잘못된 사용!
  // 올바른 사용.
  /*1)*/ item.pszText = str.GetBuffer();
  // 또는
  /*2)*/ _tcscpy_s(item.pszText, MAX_PATH, str.GetBuffer(str.GetLength()));
  ListView_SetItem ( &item );
  str.ReleaseBuffer();

참조 :
http://eroom.korea.com/post/board.aspx?bid=kmh_19505&mode=read&view=board&pid=189103&page=1

CString to DWORD

CString str=_T("abcd");
DWORD dw = (DWORD)_ttoi((LPCTSTR)str);


출처 : http://hogwarts.tistory.com/172
Posted by SB패밀리

(LPSTR)(LPCTSTR)csTest은 위험하다.!!
-. 유니코드를 고려하지 않았을뿐 아니라
-. 위험하게 내부데이터를 접근합니다.
 
CString strPP;
char * chNN = (LPSTR)(LPCSTR)strPP;
이렇게 해서 chNN을 CString의 포인터로 가져 옵니다.

(LPSTR)(LPCSTR)strPP 이 부분 에서 이유는 MSDN을 찾아보시면 아시겠지만 CString은 const char * 으로 만 받을수 있답니다.
그래서 (LPCTSTR)strPP 이런 형식으로도 사용합니다. 물론 const char *으로 return되겠죠.. 다시 char *을 필요하신다면 
char * chNN = (char *)(LPCTSTR)strPP; 이런 식으로도 사용합니다
 
char *pstr = (LPSTR)(LPCTSTR)str;        이 줄은 UNICODE인경우
    char *pstr = (char *) (const wchar_t *) str;    입니다.
특히 wchar_t를 본래데이터형으로 보지 않을 경우
    char *pstr = (char *)(const unsigned short *)str;   입니다..
 
유니코드를 고려하지 않는다고 하더라도, CString이 제공하는 것은 const 가 붙은 형변환 밖에 없는데,
이걸 const 를 억지로 빼버리고는 마치 접근해서 고쳐도 되는 것처럼 보이게 되므로
잘못사용하면 오류를 일으키며. 프로그램이 뻗을수도 있습니다.
 
const 변환은 받는 쪽에서 안고친다고 보고 CString이 자기 내부 메모리주소를 살짝 보여주는 건데..
그걸 char로 바꾸고 쓰려고 하면 당연히 에러가 발생 하겠죠...
보통 이런 문제는 char[50] 에서 처럼 .. "특정 위치의 글자를 바로 접근할 수 있냐..?"란 의문에서 생기는데
이 문제는 CString만으로도 충분합니다.

CString이 operator[] 를 제공하고 있습니다.. operator를 이용 하면 됩니다..
str[23] 이렇게 마치 char[] 처럼 사용하실수 있습니다.
물론 이때도 배열의 길이를 넘어서는 접근은 피해야 합니다.
C/C++의 배열이 제공못하는 길이를 CString은 GetLength()형태로 제공하니 얼마나 편합니까 .
출처:이상 데브피아
 
 
"이하" 파란 생각~
CString csTest = "사나이로 태어나서 할일은 사랑하기";
char* cTest = (LPSTR)(LPCTSTR)csTest;
AfxMessageBox(cTest);
 
즉, 위와 같이 무리한 형변환 보다는 CString의 Operator의 GetBuffer()을 사용해서 가지고오면 더욱 효율적입니다.
char* cTest;
CString csTest = "사나이로 태어나서 할일은 사랑하기";
cTest = csTest.GetBuffer(0);                //GetBuffer(0): csTest가 가지고 있는 문자열의 만큼 가지고 온다는 의미
AfxMessageBox(cTest);

출처 : http://blog.daum.net/sjdody/5693925
Posted by SB패밀리

VC++의 문자열 변환중 CString에 관련된 몇가지를 알아보자.


CString LPSTR WCHAR* LPCWSTR

CString to LPSTR

 CollapseCString str = _T("My String");
int nLen = str.GetLength();
LPTSTR lpszBuf = str.GetBuffer(nLen);
// here do something with lpszBuf...........

str.ReleaseBuffer();

 

LPTSTR to LPWSTR

int nLen = MultiByteToWideChar(CP_ACP, 0, lptStr, -1, NULL, NULL);
MultiByteToWideChar(CP_ACP, 0, lptStr, -1, lpwStr, nLen);


CString to WCHAR*

CString str = "A string here" ;
LPWSTR lpszW = new WCHAR[255];

LPTSTR lpStr = str.GetBuffer( str.GetLength() );
int nLen = MultiByteToWideChar(CP_ACP, 0,lpStr, -1, NULL, NULL);

MultiByteToWideChar(CP_ACP, 0, lpStr, -1, lpszW, nLen);
AFunctionUsesWCHAR( lpszW );
delete[] lpszW;


CString to LPCWSTR

CString a;
a.Format(_T("%d"), nDiffTime);
WCHAR *b;
b = a.GetBuffer(a.GetLength());

Posted by SB패밀리