Сущность технологии СОМ. Библиотека программиста | страница 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.