Сущность технологии СОМ. Библиотека программиста | страница 65
Первый вариант предпочтительней, так как он будет надежно компилироваться на всех платформах.
Поскольку часто возникает необходимость копировать строки на основе типа wchar_t в обычные буфера на основе char, то динамическая библиотека С предлагает две процедуры для преобразования типов:
size_t mbstowcs(wchar_t *pwsz, const char *psz, int cch);
size_t wcstombs(char *psz, const wchar_t *pwsz, int cch);
Эти две процедуры работают аналогично динамической С-процедуре strncpy, за исключением того, что в эти процедуры как часть операции копирования включено расширение или сужение строки. Следующий код показывает, как параметр метода, размещенный в OLECHAR, можно скопировать в элемент данных, размещенный в char:
class BigDog : public ILabrador
{
char m_szName[1024] ;
public:
STDMETHODIMP SetName(/* [in,string]*/ const OLECHAR *pwsz)
{
HRESULT hr = S_OK;
size_t cb = wcstombs(m_szName, pwsz, 1024);
// check for buffer overflow or bad conversion
// проверяем переполнение буфера или неверное преобразование
if (cb == sizeof(m_szName) || cb == (size_t)-1)
{
m_szName[0] = 0; hr = E_INVALIDARG;
}
return hr;
}
};
Этот код является довольно простым, хотя программист должен осознавать, что используются два различных типа символов. Несколько более сложный (и чаще встречающийся) случай – преобразование между типами данных OLECHAR и TCHAR из Win32. Так как OLECHAR условно компилируется как char или wchar_t, то при реализации метода необходимо должным образом рассмотреть оба сценария:
class BigDog : public ILabrador
{
TCHAR m_szName[1024];
// note TCHAR-based string
// отметим строку типа TCHAR
public:
STDMETHODIMP SetName( /*[in,string]*/ const OLECHAR *pwsz)
{
HRESULT hr = S_OK;
#ifdef UNICODE
// Unicode build (TCHAR == wchar_t)
// конструкция Unicode (TCHAR == wchar_t)
wcsncpy(m_szName, pwsz, 1024);
// check for buffer overflow
// проверка на переполнение буфера
if (m_szName[1023] != 0)
{
m_szName[0] = 0;
hr = E_INVALIDARG;
}
#else
// Non-Unicode build (TCHAR == char)
// не является конструкцией Unicode (TCHAR == char)
size_t cb = wcstombs(m_szName, pwsz, 1024);
// check for buffer overflow or bad conversion
// проверка переполнения буфера или ошибки преобразования
if (cb == sizeof(m_szName) || cb == (size_t)-1)
{
m_szName[0] =0;
hr = E_INVALIDARG;
}
#endif return hr;
}
};
Очевидно, операции с преобразованиями OLECHAR в TCHAR значительно сложнее. Но, к сожалению, это самый распространенный сценарий при программировании в СОМ на базе Win32.