Please Enable JavaScript!
Gon[ Enable JavaScript ]

ATL에서 문자열사용하기위한 방법들

기타 언어/C# & MFC
반응형

일단 기초적인 개념부터 파악하자.


USES_CONVERSION 매크로의 종류들이다.
Macro 함수의 이름은 다음과 같은 구조로 돼어있다.
[원본 타입]2[새 타입] / [원본타입]2C[새 타입]
2는 그냥 변환 / 2C는 constant pointer를 말하는 C이다.

A : MBCS 문자열 char*
W : Unicode 문자열 wchar_t*
T : TCHAR 문자열 TCHAR*
OLE : OLECHAR 문자열 OLECHAR*
BSTR : BSTR
OLECHAR* = 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)
A2BSTR(LPSTR) -> (BSTR*)

유니코드환경에서 SBCS 에서 사용하던 함수 strcpy(), sprintf(), atol()등 대신 뭘 사용해야될까?
문자를 복사하는 strcpy() 경우 str ->wsc 로 바꿔서 wcscpy(short int* ) 사용한다.
이것을 좀더 편리하게 TCHAR 처럼 상황에 맞게 자료형이 변경될수 있게 함수를 매크로로 만들어놓았다.
strrchr() / _mbsrchr() / wcsrchr() 을 구분할필요없이 _tcscpy()식으로 _t가 붙은 함수들로 대체 할 수 있다.
#ifdef UNICODE
   typedef wchar_t TCHAR;
#else
   typedef char TCHAR;
#endif
처럼
#ifdef UNICODE
   wcscpy();
#else
   strcpy();
#endif
가 될것이다.

일반함수                               유니코드함수
strcpy()                                _tcscpy()  _tscXXX()형태
sprintf()                                swprintf()  w등이 붙는다
atol()                                   _wtol()
strlen()                                _tcslen()

유니코드 매크로 함수는 tchar.h 에 정의 되어있다. 쓸만한건 찾아서 보면된다
< tchar.h >
#define _tcscat         wcscat
#define _tcscat_s       wcscat_s
#define _tcschr         wcschr
#define _tcscpy         wcscpy
#define _tcscpy_s       wcscpy_s
#define _tcscspn        wcscspn
#define _tcslen         wcslen

'''''''

COM,ATL 에서 사용될 문자열관련 함수들
아래 함수는 BSTR 을 String 형으로 바꾸는 함수예이다.
int SysStringLen(BSTR) : BSTR 의 길이값을 얻어온다.

using namespace System;
String* BSTR2SysString(BSTR bstr)
{
   int strLen = ::SysStringLen(bstr);
   Char ret[] = new Char [strLen];
   for(int idx = 0; idx < strLen; ++idx)
   {
      ret[idx] = bstr[idx];
   }
   return new String(ret);
};

SysAllocString() : BSTR 메모리 할당
SysFreeString() : BSTR 메모리 해제

HRESULT IWebBrowser2::put_StatusText( BSTR bstr );
// shows using the Win32 function
// to allocate memory for the string:
BSTR bstrStatus = ::SysAllocString( L"Some text" );
if (bstrStatus == NULL)
   return E_OUTOFMEMORY;
pBrowser->put_StatusText( bstrStatus );
// Free the string:
::SysFreeString( bstrStatus );

SysFreeString() 를 구현할때 유의 할점이있다. 메모리 해제는 호출하는 측에서 해제해야한다.
구현하는 함수에서 해제 하면 에러난다. 왜냐하면 구현함수 에서 메모리 잡아서 주소넘겨주기전에
해제해버리면 호출한측에서 그곳에 가보면 아무것도 없기 때문이다. 다음의 예이다

// 호출한 쪽
HRESULT IWebBrowser2::get_StatusText( BSTR FAR* pbstr );
//...
BSTR bstrStatus;
pBrowser->get_StatusText( &bstrStatus );
// shows using the Win32 function
// to freee the memory for the string:
::SysFreeString( bstrStatus );

// 구현한함수
//...
HRESULT CMyClass::get_StatusText( BSTR * pbstr )
{
   try
   {
      //m_str is a CString in your class
      *pbstr = m_str.AllocSysString( );
      }
   catch (...)
   {
      return E_OUTOFMEMORY;
   }
// The client is now responsible for freeing pbstr.
return( S_OK );
}







 

반응형
Posted by 녹두장군1
,