最近在看opencv,无奈老外开发的东西TMD居然没有宽字符版本。
比如一个最简单的读取位图文件的
Mat imread( const string& filename, int flags=1 );
MSDN对转换宏介绍的不清不楚的,看源文件吧
/*atlconv.h*/
#ifdef _UNICODE
#define CT2A CW2A
#else // !_UNICODE
/*
CT2A 被替换成CW2A CW2A实际是一个类
CString Wstr(_T("this is a unicode string"));
那么假如 CT2A str(Wstr);_CString重载了return LPCWSTR,因此是可以这样传递参数构造的_
就构造了一个CW2A对象,这个对象str包含一个成员LPSTR m_psz;
这个指针即转换后的窄字符buffer 指针,同样的,这个类也重载了return LPSTR,因此可以这样用
char* exo=str(Wstr);
*/
class CW2AEX
{
public:
CW2AEX(_In_z_ LPCWSTR psz) throw(...) :
m_psz( m_szBuffer )
{
Init( psz, _AtlGetConversionACP() );
}
CW2AEX(
_In_z_ LPCWSTR psz,
_In_ UINT nCodePage) throw(...) :
m_psz( m_szBuffer )
{
Init( psz, nCodePage );
}
~CW2AEX() throw()
{
AtlConvFreeMemory(m_psz,m_szBuffer,t_nBufferLength);
}
_Ret_z_ operator LPSTR() const throw()
{
return( m_psz );
}
private:
void Init(
_In_z_ LPCWSTR psz,
_In_ UINT nConvertCodePage) throw(...)
{
if (psz == NULL)
{
m_psz = NULL;
return;
}
int nLengthW = lstrlenW( psz )+1;
int nLengthA = nLengthW*4;
AtlConvAllocMemory(&m_psz,nLengthA,m_szBuffer,t_nBufferLength);
BOOL bFailed=(0 == ::WideCharToMultiByte( nConvertCodePage, 0, psz, nLengthW, m_psz, nLengthA, NULL, NULL ));
if (bFailed)
{
if (GetLastError()==ERROR_INSUFFICIENT_BUFFER)
{
nLengthA = ::WideCharToMultiByte( nConvertCodePage, 0, psz, nLengthW, NULL, 0, NULL, NULL );
AtlConvAllocMemory(&m_psz,nLengthA,m_szBuffer,t_nBufferLength);
bFailed=(0 == ::WideCharToMultiByte( nConvertCodePage, 0, psz, nLengthW, m_psz, nLengthA, NULL, NULL ));
}
}
if (bFailed)
{
AtlThrowLastWin32();
}
}
public:
LPSTR m_psz;
char m_szBuffer[t_nBufferLength];
private:
CW2AEX(_In_ const CW2AEX&) throw();
CW2AEX& operator=(_In_ const CW2AEX&) throw();
};
typedef CW2AEX<> CW2A;