Передача BSTR в ActiveX компонент на VC++ 6
От: Romantic  
Дата: 04.05.04 11:09
Оценка:
Задача такая — передать структуру данных а компонент. Для этого удобно использовать BSTR — буфер произвольной длины. Делаю я так:


unsigned long length; // необходимый размер буфера в байтах
BSTR bstr=SysAllocStringByteLen(0, length);


затем полученный BSTR передаю методу компонента.
Есть в этом коде какие-нибудь тонкие места? Дело в том, что начиная с какого-то момента программа на основе этого метода перестала работать — выдает ошибку "Недостаточно памяти для выполнения операции"
Re: Передача BSTR в ActiveX компонент на VC++ 6
От: Willi  
Дата: 04.05.04 13:05
Оценка:
Здравствуйте, Romantic, Вы писали:

R>затем полученный BSTR передаю методу компонента.

R>Есть в этом коде какие-нибудь тонкие места? Дело в том, что начиная с какого-то момента программа на основе этого метода перестала работать — выдает ошибку "Недостаточно памяти для выполнения операции"

Если я не ошибаюсь, ответственность за освобождение строки остается за тобой.
То есть после вызова метода компонента, ты должен вызвать SysFreeString.
\/\/i||i
Re[2]: Передача BSTR в ActiveX компонент на VC++ 6
От: EM Великобритания  
Дата: 04.05.04 13:11
Оценка:
Здравствуйте, Willi, Вы писали:

W>Если я не ошибаюсь, ответственность за освобождение строки остается за тобой.

W>То есть после вызова метода компонента, ты должен вызвать SysFreeString.

Совершенно верно — освобождать строку должен тот, кто выделил, т.е. клиент.
Опыт — это такая вещь, которая появляется сразу после того, как была нужна...
Re[3]: Передача BSTR в ActiveX компонент на VC++ 6
От: Willi  
Дата: 04.05.04 13:41
Оценка:
Здравствуйте, EM, Вы писали:

EM>Совершенно верно — освобождать строку должен тот, кто выделил, т.е. клиент.


Точнее будет сказать так: освобождать всегда должен клиент
Поскольку в случае, когда строковый парметр [out], его выделяет сервер.
\/\/i||i
Re[4]: Передача BSTR в ActiveX компонент на VC++ 6
От: EM Великобритания  
Дата: 04.05.04 13:49
Оценка: 10 (2)
Здравствуйте, Willi, Вы писали:

W>Здравствуйте, EM, Вы писали:


EM>>Совершенно верно — освобождать строку должен тот, кто выделил, т.е. клиент.


W>Точнее будет сказать так: освобождать всегда должен клиент

W>Поскольку в случае, когда строковый парметр [out], его выделяет сервер.

Тоже верно, опечатался.
В случае [in] выделяет и освобождает клиент
В случае [in,out] выделяет клиент, перевыделяет сервер, освобождает клиент
В случае [out] освобождает клиент, выделяет сервер.
т.е. в любом случае память освобождает клиент
Опыт — это такая вещь, которая появляется сразу после того, как была нужна...
Re[5]: Передача BSTR в ActiveX компонент на VC++ 6
От: Аноним  
Дата: 04.05.04 19:04
Оценка:
Здравствуйте, господа!

Совершенно с вами согласен. Извиняюсь, что не довел до конца мысль — действительно, строка освобождается клиентом после окончания операции — благо она синхронная. Проблема в том, что с некоторого момента перестала работать вся эта схема. У меня возникли сомнения — не нужно ли по-другому обозначать длину строки — ведь бейсиковские строки содержат длину в первом элементе. Может быть, функция SysAllocStringByteLen не заполняет или заполняет неправильно слово, содержащее длину строки? Если так — то может, его нужно заполнять собственноручно?

Искренне признателен за внимание!
Re[6]: Передача BSTR в ActiveX компонент на VC++ 6
От: Кодт Россия  
Дата: 04.05.04 23:16
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Совершенно с вами согласен. Извиняюсь, что не довел до конца мысль — действительно, строка освобождается клиентом после окончания операции — благо она синхронная. Проблема в том, что с некоторого момента перестала работать вся эта схема. У меня возникли сомнения — не нужно ли по-другому обозначать длину строки — ведь бейсиковские строки содержат длину в первом элементе. Может быть, функция SysAllocStringByteLen не заполняет или заполняет неправильно слово, содержащее длину строки? Если так — то может, его нужно заполнять собственноручно?


Всё заполняет нормально. Ищи утечку.

А не хочешь ли ты вместо голого BSTR использовать умные указатели?
А может, вообще вместо BSTR обойтись WCHAR* ?

ЗЫ.
Длина BSTR хранится не в первом элементе, а по смещению -4. Начиная со смещения 0 идёт обычная юникодная строка с 0 на конце.
Перекуём баги на фичи!
Re[7]: Передача BSTR в ActiveX компонент на VC++ 6
От: Romantic  
Дата: 05.05.04 04:49
Оценка: 2 (1) +1
Здравствуйте, Кодт, Вы писали:

К>А не хочешь ли ты вместо голого BSTR использовать умные указатели?

К>А может, вообще вместо BSTR обойтись WCHAR* ?

Дело в том, что при копировании wchar* строки копирование производится только до 0-символа, тогда как для BSTR система знает точную длину буфера. А в упакованном объекте запросто может быть последовательность нулевых байт.
Re[7]: Передача BSTR в ActiveX компонент на VC++ 6
От: Willi  
Дата: 05.05.04 05:08
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Длина BSTR хранится не в первом элементе, а по смещению -4. Начиная со смещения 0 идёт обычная юникодная строка с 0 на конце.


Если быть педантом, то BSTR допускает наличие нулей и в середине строки.
\/\/i||i
Re[8]: Передача BSTR в ActiveX компонент на VC++ 6
От: EM Великобритания  
Дата: 05.05.04 07:51
Оценка:
Здравствуйте, Willi, Вы писали:

W>Здравствуйте, Кодт, Вы писали:


К>>Длина BSTR хранится не в первом элементе, а по смещению -4. Начиная со смещения 0 идёт обычная юникодная строка с 0 на конце.


W>Если быть педантом, то BSTR допускает наличие нулей и в середине строки.



[msdn]
These strings are zero-terminated, and in most cases they can be treated just like OLECHAR* strings. However, you can query a BSTR for its length rather than scan it, so it can contain embedded null characters.
[/msdn]
Опыт — это такая вещь, которая появляется сразу после того, как была нужна...
Re[9]: Передача BSTR в ActiveX компонент на VC++ 6
От: Willi  
Дата: 05.05.04 08:17
Оценка:
Здравствуйте, EM, Вы писали:

К>>>Длина BSTR хранится не в первом элементе, а по смещению -4. Начиная со смещения 0 идёт обычная юникодная строка с 0 на конце.


W>>Если быть педантом, то BSTR допускает наличие нулей и в середине строки.


EM>[msdn]

EM>These strings are zero-terminated, and in most cases they can be treated just like OLECHAR* strings. However, you can query a BSTR for its length rather than scan it, so it can contain embedded null characters.
EM>[/msdn]

Сдается мне, мы говорим об одном и том же

These strings are zero-terminated, and in most cases they can be treated just like OLECHAR* strings. However, you can query a BSTR for its length rather than scan it, so it can contain embedded null characters.

\/\/i||i
Re[10]: Передача BSTR в ActiveX компонент на VC++ 6
От: KGP http://kornilow.newmail.ru
Дата: 06.05.04 07:44
Оценка:
Здравствуйте, Willi, Вы писали:

ибо впереди храниться длинна строки, а потом данные, потому и ограничений на данные нет НИКАКИХ
... << RSDN@Home 1.1.2 stable >>
Re[8]: Передача BSTR в ActiveX компонент на VC++ 6
От: Дмитрий Наумов  
Дата: 06.05.04 10:05
Оценка: 15 (1)
Здравствуйте, Willi, Вы писали:

W>Здравствуйте, Кодт, Вы писали:


К>>Длина BSTR хранится не в первом элементе, а по смещению -4. Начиная со смещения 0 идёт обычная юникодная строка с 0 на конце.


W>Если быть педантом, то BSTR допускает наличие нулей и в середине строки.


Есть хорошая статья по этому поводу.
http://weblogs.asp.net/ericlippert/archive/2003/09/12/52976.aspx
... << RSDN@Home 1.1.3 beta 2 >>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.