этот код компилируется и работает как ожидалось, и я всегда так раньше делал ... но меня терзают сомнения, что необходимо явно создавать BSTR, тоесть например так:
сомнения эти меня посетили после того, как я поработал с COM объектом написанном на васике. при передачи LPCWSTR в его методы ожидающие [in]BSTR, сам COM объект получает пустую строку, при явном создании BSTR все проходит как надо...
Здравствуйте, ssm, Вы писали:
>насколько правомерным является передача в метод ожидающий BSTR, значения типа LPCWSTR?
Все зависит от наличия маршаллинга. Если компонент загружен inproc и используется "ранее связывание", то, скорее всего, строка будет передана и через LPWSTR. Если же имеется маршаллинг, то нужно конвертировать в BSTR. Маршаллер читает размер необходимого буфера из строки. У меня были случаи, когда вызов метода пытался захватить несколько гигов памяти из-за этой ошибки. Также, ошибка может быть "нестабильной" — как повезет.
Здравствуйте, rus blood, Вы писали:
RB>Здравствуйте, ssm, Вы писали:
RB>Все зависит от наличия маршаллинга. Если компонент загружен inproc и используется "ранее связывание", то, скорее всего, строка будет передана и через LPWSTR. Если же имеется маршаллинг, то нужно конвертировать в BSTR. Маршаллер читает размер необходимого буфера из строки. У меня были случаи, когда вызов метода пытался захватить несколько гигов памяти из-за этой ошибки. Также, ошибка может быть "нестабильной" — как повезет.
RB>Корректно все таки конвертировать в BSTR всегда.
Кроме того, есть устойчивые подозрения, что для переданного LPWSTR функция SysStringLen вернет мусор, поскольку для BSTR длина хранится в четырех байтах ПЕРЕД значением самого указателя BSTR, а в твоем случае там будет мусор.
It's kind of fun to do the impossible (Walt Disney)
Здравствуйте, rus blood, Вы писали:
RB>Здравствуйте, ssm, Вы писали:
RB>Если компонент загружен inproc и используется "ранее связывание", то, скорее всего, строка будет передана и через LPWSTR.
Думаю, нет. Весь вопрос в том, как эту строку пытаются использовать, точнее, как пытаются определить её длинну.
RB>Корректно все таки конвертировать в BSTR всегда.
Вот тут согласен.
Лучший дар, который мы получили от природы и который лишает нас всякого права жаловаться – это возможность сбежать. /М.Монтень/
И еще в догонку. BSTR может содержать несколько символов конца строки. Соответственно без счетика символов в начале, такая строка не имеет смысла и сэмулировать такую ситуацию используя LPCWSTR невозможно.
Здравствуйте, NKZ, Вы писали:
NKZ>И еще в догонку. BSTR может содержать несколько символов конца строки. Соответственно без счетика символов в начале, такая строка не имеет смысла и сэмулировать такую ситуацию используя LPCWSTR невозможно.
Почему же так категорично?
// client
pServer->Method(L"token1\0token2\0");
// server
HRESULT CServer::Method(BSTR bstr)
{
LPWSTR lpPoint = (LPWSTR)bstr;
while (*lpPoint)
{
// do something with token
....
// continue with next
lpPoint += wcslen(lpPoint) + 1;
}
}
Здравствуйте, rus blood, Вы писали:
RB>Здравствуйте, ssm, Вы писали:
RB>Все зависит от наличия маршаллинга. Если компонент загружен inproc и используется "ранее связывание", то, скорее всего, строка будет передана и через LPWSTR. Если же имеется маршаллинг, то нужно конвертировать в BSTR. Маршаллер читает размер необходимого буфера из строки. У меня были случаи, когда вызов метода пытался захватить несколько гигов памяти из-за этой ошибки. Также, ошибка может быть "нестабильной" — как повезет.
Не только от маршалинга. Когда-то долго мучился на ADO, требовалось именно BSTR, а с WCHAR давал runtime error. Пока нашел особенность, потерял много времени и стал более блондинистым.
RB>Корректно все таки конвертировать в BSTR всегда.
Если это не твоя библиотека, то всегда!