в idl файле определена стуктура в которую входит LPTSTR pszText;
при использовании #import клиент видит это поле как LPWSTR pszText;(tlh файл)
в клиенте написан вот такой код
WCHAR pWcharText[256] = _T("Text");
lvc.pszText = pWcharText
потом стуктура передается как параметр функции com сервера
внутри функции оказалось что lvc.pszText содержит только один первый символ
что не правильно при использовании LPTSTR ?
Здравствуйте Аноним, Вы писали:
А>в idl файле определена стуктура в которую входит LPTSTR pszText; А>при использовании #import клиент видит это поле как LPWSTR pszText;(tlh файл) А>в клиенте написан вот такой код А>WCHAR pWcharText[256] = _T("Text"); А>lvc.pszText = pWcharText
А>потом стуктура передается как параметр функции com сервера А>внутри функции оказалось что lvc.pszText содержит только один первый символ А>что не правильно при использовании LPTSTR ?
Причуды маршаллинга LPWSTR — просто указатель, маршаллер достаточно умный, чтобы догадаться передать элемент, на который он указывает, но недостаточно умный, чтобы догадаться, сколько там на самом деле символов. Надо использовать BSTR.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте Sergey, Вы писали:
S>Здравствуйте Аноним, Вы писали:
А>>в idl файле определена стуктура в которую входит LPTSTR pszText; А>>при использовании #import клиент видит это поле как LPWSTR pszText;(tlh файл) А>>в клиенте написан вот такой код А>>WCHAR pWcharText[256] = _T("Text"); А>>lvc.pszText = pWcharText
А>>потом стуктура передается как параметр функции com сервера А>>внутри функции оказалось что lvc.pszText содержит только один первый символ А>>что не правильно при использовании LPTSTR ?
S>Причуды маршаллинга LPWSTR — просто указатель, маршаллер достаточно умный, чтобы догадаться передать элемент, на который он указывает, но недостаточно умный, чтобы догадаться, сколько там на самом деле символов. Надо использовать BSTR.
Позволю себе не согласиться с таким объяснением. MIDL compiler корректно транспортирует строки по указателям. В том числе в составе структур, нужно лишь построить и зарегистрировать dll заглушки — прокси. Я не пробовал проверять это при исползовании #import, хотя не думаю, чтобы там что-то помешало нормальному ходу процесса.
Vaso
Re[3]: использование LPTSTR в COM
От:
Аноним
Дата:
23.05.02 07:21
Оценка:
Здравствуйте Vaso, Вы писали:
V>Здравствуйте Sergey, Вы писали:
S>>Здравствуйте Аноним, Вы писали:
А>>>в idl файле определена стуктура в которую входит LPTSTR pszText; А>>>при использовании #import клиент видит это поле как LPWSTR pszText;(tlh файл) А>>>в клиенте написан вот такой код А>>>WCHAR pWcharText[256] = _T("Text"); А>>>lvc.pszText = pWcharText
А>>>потом стуктура передается как параметр функции com сервера А>>>внутри функции оказалось что lvc.pszText содержит только один первый символ А>>>что не правильно при использовании LPTSTR ?
S>>Причуды маршаллинга :-\ LPWSTR — просто указатель, маршаллер достаточно умный, чтобы догадаться передать элемент, на который он указывает, но недостаточно умный, чтобы догадаться, сколько там на самом деле символов. Надо использовать BSTR.
V>Позволю себе не согласиться с таким объяснением. MIDL compiler корректно транспортирует строки по указателям. В том числе в составе структур, нужно лишь построить и зарегистрировать dll заглушки — прокси. Я не пробовал проверять это при исползовании #import, хотя не думаю, чтобы там что-то помешало нормальному ходу процесса.
решение проблемы оказалось простым и интересным:
клиент был скомпилирован с preprocessor definitions как UNICODE а сервер как _MBCS.после того как сервер скомпилил как UNICODE строка стала передаваться корректно.
Здравствуйте Vaso, Вы писали:
V>Позволю себе не согласиться с таким объяснением. MIDL compiler корректно транспортирует строки по указателям. В том числе в составе структур, нужно лишь построить и зарегистрировать dll заглушки — прокси. Я не пробовал проверять это при исползовании #import, хотя не думаю, чтобы там что-то помешало нормальному ходу процесса.
Чем отличается в IDL-файле такие описания (WIN32):
[...] HRESULT func( [in] LPWSTR buf )
от
[...] HRESULT func( [in] unsigned short* buf )
или от
[...] HRESULT func( [in] BSTR buf )
И сколько информации будет передаваться ЛЮБЫМ маршаллером при таком описании?
Первые два случая вообще эквиваленты — передаются 2 байта, причём любым маршаллером, а третий отличается, потому как MIDL не равнодушен именно к имени "BSTR", хотя оно тоже "unsigned short*".
Поэтому выход, правильно предложенный Sergey:
или использовать size_is (и т.п.) и свой маршаллер
или использовать BSTR
Vi2>И сколько информации будет передаваться ЛЮБЫМ маршаллером при таком описании? Vi2>Первые два случая вообще эквиваленты — передаются 2 байта, причём любым маршаллером, а третий отличается, потому как MIDL не равнодушен именно к имени "BSTR", хотя оно тоже "unsigned short*".
Vi2>Поэтому выход, правильно предложенный Sergey: Vi2>
Vi2>или использовать size_is (и т.п.) и свой маршаллер Vi2>или использовать BSTR Vi2>
А ты попробуй на досуге так не заморачиваться, а просто передать LPCTSTR. Уверен, у тебя получится. Ответ содержится в твоем вопросе: BSTR тоже раскрывается в LPWSTR, но маршалится особым образом. Почему? Видимо потому, что для MIDL compiler'а в отличие от cl.exe LPWSTR != unsigned short* != BSTR. Код для заглушек/прокси получается разный. Я так думаю...
Здравствуйте Vaso, Вы писали:
V>А ты попробуй на досуге так не заморачиваться, а просто передать LPCTSTR. Уверен, у тебя получится. Ответ содержится в твоем вопросе: BSTR тоже раскрывается в LPWSTR, но маршалится особым образом. Почему? Видимо потому, что для MIDL compiler'а в отличие от cl.exe LPWSTR != unsigned short* != BSTR. Код для заглушек/прокси получается разный. Я так думаю...
А ты хочешь, чтобы твой сервер работал/не работал в зависимости от того, как откомпилируют клиентов?
Желание использовать LPCTSTR в IDL можно расшифровать только так. BSTR — рекомендации лучших собаководов.
Здравствуйте retalik, Вы писали:
R>А ты хочешь, чтобы твой сервер работал/не работал в зависимости от того, как откомпилируют клиентов?
LPCTSTR конечно же применяется в таких случаях только внутри проекта. Внешние интерфейсы конечно же используют конкретные LPCSTR/LPCWSTR, это понятно, спор-то ведь был не об этом.
R>Желание использовать LPCTSTR в IDL можно расшифровать только так. BSTR — рекомендации лучших собаководов.
BSTR неприемлем во многих случаях из-за большей ресурсоемкости, и, например в ANSI — ых проектах из-за необходимости конвертации ( можно, конечно, и ANSI — строки передавать через BSTR, но это тоже потребует дополнительных действий и ресурсов ). Так что остаюсь при своем мнении.
Здравствуйте Vaso, Вы писали:
V>Здравствуйте retalik, Вы писали:
R>>А ты хочешь, чтобы твой сервер работал/не работал в зависимости от того, как откомпилируют клиентов?
почему же он небудет работать ?
в preprocessor definitions у сервера стоит ,_MBCS,_UNICODE
для ANSI клиентов при использовании #import В tlh будет LPSTR pszText;
к тому же эта программа ориентирована на NT платформы
R>>Желание использовать LPCTSTR в IDL можно расшифровать только так. BSTR — рекомендации лучших собаководов.
LPCTSTR нужен мне вот для чего:
сервер является activex'om
я хоче напрямую передавать из клиента в activex экземпляр такой структуры:
struct _MY_LVCOLUMN
{
unsigned int mask;
int fmt;
int cx;
LPTSTR pszText;
int cchTextMax;
int iSubItem;
int iOrder;
int iImage;
};
// реализация метода сервера
STDMETHODIMP CMyListViewCtrl::My_InsertColumn(int nCol,const MY_LVCOLUMN* pColumn)
{
HRESULT hr = S_OK;
ASSERT(::IsWindow(m_ctlSysListView32.m_hWnd));