Hungry Mind , Blog about everything in IT - C#, Java, C++, .NET, Windows, WinAPI, ...

Use ATL string convertion properly

В ATL 7 появилось новое семейство СX2Y макросов для конвертации строк из текущей кодовой страницы в UNICODE и обратно. И я заметил, что их часто используют абсолютно неправильно! Например:

const std::wstring some = L"Some";
AfxMessageBox(CW2T(some.c_str()));

Код выглядит, как не содержащий ошибок. Но на самом деле это не так. Взгляните на макрос CW2T когда определен _UNICODE (atlconv.h):

#ifdef _UNICODE

    #define CW2T CW2W

А теперь самое интересное:

template< int t_nBufferLength = 128 >
class CW2WEX
{
public:
    CW2WEX( _In_opt_ LPCWSTR psz ) throw(...) :
        m_psz( m_szBuffer )
    {
        Init( psz );
    }
    CW2WEX( _In_opt_ LPCWSTR psz, UINT nCodePage ) throw(...) :
        m_psz( m_szBuffer )
    {
        (void)nCodePage;  // Code page doesn't matter

        Init( psz );
    }
    ~CW2WEX() throw()
    {
        AtlConvFreeMemory(m_psz,m_szBuffer,t_nBufferLength);
    }

    operator LPWSTR() const throw()
    {
        return( m_psz );
    }

private:
    void Init( _In_opt_ LPCWSTR psz ) throw(...)
    {
        if (psz == NULL)
        {
            m_psz = NULL;
            return;
        }
        int nLength = lstrlenW( psz )+1;
        AtlConvAllocMemory(&m_psz,nLength,m_szBuffer,t_nBufferLength);
        ATLASSUME(m_psz != NULL);
        Checked::memcpy_s( m_psz, nLength*sizeof( wchar_t ), psz, nLength*sizeof( wchar_t ));
    }

public:
    LPWSTR m_psz;
    wchar_t m_szBuffer[t_nBufferLength];

private:
    CW2WEX( const CW2WEX& ) throw();
    CW2WEX& operator=( const CW2WEX& ) throw();
};
typedef CW2WEX<> CW2W;

CW2WEX выполняет копирование строки даже в случае, когда этого можно избежать, как в примере выше!

Используйте макросы CX2CY чтобы избежать лишнего копирования строк:

#ifdef _UNICODE

    #define CW2T CW2W
    #define CW2TEX CW2WEX
    #define CW2CT CW2CW
    #define CW2CTEX CW2CWEX
    #define CT2W CW2W
    #define CT2WEX CW2WEX
    #define CT2CW CW2CW
    #define CT2CWEX CW2CWEX

template< int t_nBufferLength = 128 >
class CW2CWEX
{
public:
    CW2CWEX( _In_ LPCWSTR psz ) throw(...) :
        m_psz( psz )
    {
    }
    CW2CWEX( _In_ LPCWSTR psz, UINT nCodePage ) throw(...) :
        m_psz( psz )
    {
        (void)nCodePage;
    }
    ~CW2CWEX() throw()
    {
    }

    operator LPCWSTR() const throw()
    {
        return( m_psz );
    }

public:
    LPCWSTR m_psz;

private:
    CW2CWEX( const CW2CWEX& ) throw();
    CW2CWEX& operator=( const CW2CWEX& ) throw();
};
typedef CW2CWEX<> CW2CW;

1 коммент.:

Анонимный комментирует...

I was recommended this website by my cousin.
I'm not sure whether this post is written by him as nobody else know such detailed about my problem. You are incredible! Thanks!
http://idientertainment.co.uk/groups/online-education-with-an-on-line-mathematical-tutor/
http://maharashtra.indiajust.in/groups/creating-outstanding-reading-through-quirks-by-using-our-tutor/

my site ... baseball bat

Отправить комментарий

Copyright 2007-2011 Chabster