통합검색
· 마을서비스란?  · 포럼마을  · 일반마을  · 테마마을  · 마을랭킹  · 활동왕
· 덱스퍼트란?  · TECBOX   · PRSBOX   · 이용안내  
· DEXT제품군  · 솔루션베이  · S/W & ESD 컴포넌트
· 프로그램베이
· LiveSeminar  · LiveConference
Visual C++ 포럼마을 입니다.
  마을등급 Visual C++   이 마을은 포럼마을 입니다이 마을은 자유가입제 마을 입니다 마을소개 페이지로 이동 전입신청
마을촌장촌장 나성훈 주민 34024 since 2006-12-29
우리마을 공지사항
질문&답변
강좌&팁
자유게시판
자료실
앨범
개인게시판
마을 게시판
등록된 마을 게시판이
없습니다.
랑데브 게시판
칼럼 게시판
개발자 고충상담
Dev Talk
자유토론방
벼룩시장
재나미 우스개
구인/프로젝트 정보
사람인 채용 게시판
  고객지원 게시판
마이 데브피아
 나의 e-Money 내역
 활동왕 My Page
 스크랩한 게시글보기
 쪽지관리
 주소록관리

 강좌&팁
 USES_CONVERSION을 사용하장..  | ATL 2001-12-19 오후 1:55:11
조경민 번호: 3638  / 읽음:6,646
오후 3:39 2000-05-03
조경민 USES_COMVERSION (bro@shinbiro.com)
====================================================

BSTR test( BSTR bstrVal )
{
  USES_CONVERSION;
  char* pszVal;
  W2A(bstrVal,pszVal);
  하면 pszVal 안에 BSTR문자열값이 들어간다.

  BSTR bstrCopy;
  A2W(pszVal,bstrCopy);
  하면 pszVal값이 bstrCopy에 들어간다. SysAlloc된 상태

     사용후 
  SysFreeString(bstrCopy);해야 함

  BSTR bstrRet;
  A2W(pszVal,bstrRet); 

  return bstrRet;    // ATL컴포넌트 메소드가 BSTR리턴시
}                    // SysAlloc후 리턴한다.
                     // VC Client에서 SysFreeString해야함
                     // VB Client에서는 알아서 프리시킴

BSTR<->char* 컨버팅이 간편한 

USES_CONVERSION을 쓰려면...

1. ATL Project
 -> 그냥 쓸수 있다.

2. MFC Project
 -> #include <comdef.h>
    #include <afxpriv.h>

3. Win32 Dll Project
#include <comdef.h>
#include <CRTDBG.H>
#include <atlconv.h>

를 하면 된다. ( 하나씩 찾아봤음 -_-;)


COM에서 WideChar와 AnsiChar 바꾸는 매크로

VARIANT에 문자열 넣기

// com support class
#include <comdef.h>
#include <AFXPRIV.H>    // USES_CONVERSION 이 정의된 곳

USES_CONVERSION;    
VARIANT var;
VariantInit(&var);
var.vt = VT_BSTR;
var.bstrVal = SysAllocString(A2W("하하하하하"));


*웹페이지에서는 문자열은 VARIANT를 써야 한다.



다음은 ASP서포트 상태에서 BSTR과 char*사이의 변환이다.

    if( m_piServer )
    {
        USES_CONVERSION;
        BSTR bstrLogicPath, bstrPhysicPath;
        bstrLogicPath = SysAllocString(A2W("/NstChart"));
        
        m_piServer->MapPath( bstrLogicPath, &bstrPhysicPath)

        SysFreeString( bstrLogicPath );
        
        char* pszPhysicPath = W2A(bstrPhysicPath);
                
        m_plgManager->fnSetPlugPath( pszPhysicPath );

    }



------------------------------------------------------------------
참고 테크니컬 노트
TN059: Using MFC MBCS/Unicode Conversion Macros
This note describes how to use the macros for MBCS/Unicode conversion which are defined in 
AFXPRIV.H. These macros are most useful if your application deals directly with the OLE API or for 
some reason, often needs to convert between Unicode and MBCS.

Overview

In MFC 3.x, a special DLL was used (MFCANS32.DLL) to automatically convert between Unicode and MBCS 
when OLE interfaces were called. This DLL was an almost transparent layer that allowed OLE 
applications to be written as if the OLE APIs and interfaces were MBCS, even though they are always 
Unicode (except on the Macintosh). While this layer was convenient and allowed applications to be 
quickly ported from Win16 to Win32 (MFC, Microsoft Word, Microsoft Excel, and VBA, are just some of 
the Microsoft applications that used this technology), it also had a sometimes significant 
performance hit. For this reason, MFC 4.x does not use this DLL and instead talks directly to the 
Unicode OLE interfaces. To do this, MFC needs to convert to Unicode to MBCS when making a call to 
an OLE interface, and often needs to convert to MBCS from Unicode when implementing an OLE 
interface. In order to handle this efficiently and easily, a number of macros were created to make 
this conversion easier.

One of the biggest hurdles of creating such a set of macros is memory allocation. Because the 
strings cannot be converted in place, new memory to hold the converted results must be allocated. 
This could have been done with code similar to the following:

// we want to convert an MBCS string in lpszA
int nLen = MultiByteToWideChar(CP_ACP, 0,lpszA, -1, NULL, NULL);
LPWSTR lpszW = new WCHAR[nLen];
MultiByteToWideChar(CP_ACP, 0, 
lpszA, -1, lpszW, nLen);
// use it to call OLE here
pI->SomeFunctionThatNeedsUnicode(lpszW);
// free the string
delete[] lpszW;

This approach as a number of problems. The main problem is that it is a lot of code to write, test, 
and debug. Something that was a simple function call, is now much more complex. In addition, there 
is a significant runtime overhead in doing so. Memory has to be allocated on the heap and freed 
each time a conversion is done. Finally, the code above would need to have appropriate #ifdefs 
added for Unicode and Macintosh builds (which don’t require this conversion to take place).

The solution we came up with is to create some macros which 1) mask the difference between the 
various platforms, and 2) use an efficient memory allocation scheme, and 3) are easy to insert into 
the existing source code. Here is an example of one of the definitions:

#define A2W(lpa) (    ((LPCSTR)lpa == NULL) ? NULL : (           _convert = (strlen(lpa)+1),        AfxA2WHelper((LPWSTR) alloca(_convert*2), 
lpa, _convert)    ))

Using this macro instead of the code above and things are much simpler:

// use it to call OLE here
USES_CONVERSION;
pI->SomeFunctionThatNeedsUnicode(T2OLE(lpszA));

There are extra calls where conversion is necessary, but using the macros is simple and effective.

The implementation of each macro uses the _alloca() function to allocate memory from the stack 
instead of the heap. Allocating memory from the stack is much faster than allocating memory on the 
heap, and the memory is automatically freed when the function is exited. In addition, the macros 
avoid calling MultiByteToWideChar (or WideCharToMultiByte) more than one time. This is done by 
allocating a little bit more memory than is necessary. We know that an MBC will convert into at 
most one WCHAR and that for each WCHAR we will have a maximum of two MBC bytes. By allocating a 
little more than necessary, but always enough to handle the conversion the second call second call 
to the conversion function is avoided. The call to the helper function AfxA2Whelper reduces the 
number of argument pushes that must be done in order to perform the conversion (this results in 
smaller code, than if it called MultiByteToWideChar directly).

In order to for the macros to have space to store the a temporary length, it is necessary to 
declare a local variable called _convert that does this in each function that uses the conversion 
macros. This is done by invoking the USES_CONVERSION macro as seen above in the example.

There are both generic conversion macros and OLE specific macros. These two different macro sets 
are discussed below. All of the macros reside in AFXPRIV.H.

Generic Conversion Macros

The generic conversion macros form the underlying mechanism. The macro example and implementation 
shown in the previous section, A2W, is one such “generic” macro. It has no relation to OLE 
specifically. The set of generic macros is listed below:

A2CW        (LPCSTR) -> (LPCWSTR)
A2W        (LPCSTR) -> (LPWSTR)
W2CA        (LPCWSTR) -> (LPCSTR)
W2A        (LPCWSTR) -> (LPSTR)

Besides doing text conversions, there are also macros and helper functions for converting 
TEXTMETRIC, DEVMODE, BSTR, and OLE allocated strings. These macros are beyond the scope of this 
discussion ? refer to AFXPRIV.H for more information on those macros.

OLE Conversion Macros

The OLE conversion macros are designed specifically for handling functions which expect OLESTR 
characters. If you examine the OLE headers you will see many references to LPCOLESTR and OLECHAR. 
These types are used to refer to the type of characters used in OLE interfaces in a way that is not 
specific to the platform. OLECHAR maps to char in Win16 and Macintosh platforms and WCHAR in Win32.

In order to keep the number of #ifdef directives in the MFC code to a minimum we have a similar 
macro for each conversion that where OLE strings are involved. The following macros are the most 
commonly used:

T2COLE    (LPCTSTR) -> (LPCOLESTR)
T2OLE    (LPCTSTR) -> (LPOLESTR)
OLE2CT    (LPCOLESTR) -> (LPCTSTR)
OLE2T    (LPCOLESTR) -> (LPCSTR)

Again there are similar macros for doing TEXTMETRIC, DEVMODE, BSTR, and OLE allocated strings. 
Refer to AFXPRIV.H for more information.

Other Considerations

Don’t use the macros in a tight loop. For example, you do NOT want to write the following kind of 
code:

void BadIterateCode(LPCTSTR lpsz)
{
USES_CONVERSION;
for (int ii = 0; ii < 10000; ii++)
pI->SomeMethod(ii, T2COLE(lpsz));
}

The code above could result in allocating megabytes of memory on the stack depending on what the 
contents of the string lpsz is!  It also takes time to convert the string for each iteration of the 
loop. Instead move such constant conversions out of the loop:

void MuchBetterIterateCode(LPCTSTR lpsz)
{
USES_CONVERSION;
LPCOLESTR lpszT = T2COLE(lpsz);
for (int ii = 0; ii < 10000; ii++)
pI->SomeMethod(ii, lpszT);
}

If the string is not constant, then encapsulate the method call into a function. This will allow 
the conversion buffer to be freed each time. For example:

void CallSomeMethod(int ii, LPCTSTR lpsz)
{
USES_CONVERSION;
pI->SomeMethod(ii, T2COLE(lpsz));
}

void MuchBetterIterateCode2(LPCTSTR* lpszArray)
{
for (int ii = 0; ii < 10000; ii++)
CallSomeMethod(ii, lpszArray[ii]);
}

Never return the result of one of the macros, unless the return value implies making a copy of the 
data before the return. For example, this code is bad:

LPTSTR BadConvert(ISomeInterface* pI)
{
USES_CONVERSION;
LPOLESTR lpsz = NULL;
pI->GetFileName(&lpsz);
LPTSTR lpszT = OLE2T(lpsz);
CoMemFree(lpsz);
return lpszT; // bad! returning alloca memory
}

The code above could be fixed by changing the return value to something which copies the value:

CString BetterConvert(ISomeInterface* pI)
{
USES_CONVERSION;
LPOLESTR lpsz = NULL;
pI->GetFileName(&lpsz);
LPTSTR lpszT = OLE2T(lpsz);
CoMemFree(lpsz);
return lpszT; // CString makes copy
}

The macros are easy to use and easy to insert into your code, but as you can tell from the caveats 
above, you need to be careful when using them.
코멘트쓰기
  좋음   놀람   궁금   화남   슬픔   최고   침묵   시무룩   부끄럼   난감
* 코멘트는 500자 이내(띄어쓰기 포함)로 적어주세요.
목록 보기   지금 보고 계시는 글을 회원님의 my Mblog >> 스크랩에 넣어두고 다음에 바로 보실 수 있습니다.  
회사소개  |   개인정보취급방침  |  제휴문의  |   광고문의  |   E-Mail 무단수집거부  |   고객지원  |   이용안내  |   세금계산서
사업자등록번호 안내: 220-81-90008 / 통신판매업신고번호 제 2017-서울구로-0055호 / 대표: 홍영준, 서민호
08390, 서울시 구로구 디지털로32길 30, 1211호 / TEL. 02_6719_6200 / FAX. 02-6499-1910
Copyright ⓒ (주) 데브피아. All rights reserved.