Задача такая — передать структуру данных а компонент. Для этого удобно использовать BSTR — буфер произвольной длины. Делаю я так:
unsigned long length; // необходимый размер буфера в байтах
BSTR bstr=SysAllocStringByteLen(0, length);
затем полученный BSTR передаю методу компонента.
Есть в этом коде какие-нибудь тонкие места? Дело в том, что начиная с какого-то момента программа на основе этого метода перестала работать — выдает ошибку "Недостаточно памяти для выполнения операции"
Здравствуйте, Romantic, Вы писали:
R>затем полученный BSTR передаю методу компонента. R>Есть в этом коде какие-нибудь тонкие места? Дело в том, что начиная с какого-то момента программа на основе этого метода перестала работать — выдает ошибку "Недостаточно памяти для выполнения операции"
Если я не ошибаюсь, ответственность за освобождение строки остается за тобой.
То есть после вызова метода компонента, ты должен вызвать SysFreeString.
\/\/i||i
Re[2]: Передача BSTR в ActiveX компонент на VC++ 6
Здравствуйте, Willi, Вы писали:
W>Если я не ошибаюсь, ответственность за освобождение строки остается за тобой. W>То есть после вызова метода компонента, ты должен вызвать SysFreeString.
Совершенно верно — освобождать строку должен тот, кто выделил, т.е. клиент.
Опыт — это такая вещь, которая появляется сразу после того, как была нужна...
Re[3]: Передача BSTR в ActiveX компонент на VC++ 6
Здравствуйте, 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
Здравствуйте, Аноним, Вы писали:
А>Совершенно с вами согласен. Извиняюсь, что не довел до конца мысль — действительно, строка освобождается клиентом после окончания операции — благо она синхронная. Проблема в том, что с некоторого момента перестала работать вся эта схема. У меня возникли сомнения — не нужно ли по-другому обозначать длину строки — ведь бейсиковские строки содержат длину в первом элементе. Может быть, функция SysAllocStringByteLen не заполняет или заполняет неправильно слово, содержащее длину строки? Если так — то может, его нужно заполнять собственноручно?
Всё заполняет нормально. Ищи утечку.
А не хочешь ли ты вместо голого BSTR использовать умные указатели?
А может, вообще вместо BSTR обойтись WCHAR* ?
ЗЫ.
Длина BSTR хранится не в первом элементе, а по смещению -4. Начиная со смещения 0 идёт обычная юникодная строка с 0 на конце.
Перекуём баги на фичи!
Re[7]: Передача BSTR в ActiveX компонент на VC++ 6
Здравствуйте, Кодт, Вы писали:
К>А не хочешь ли ты вместо голого BSTR использовать умные указатели? К>А может, вообще вместо BSTR обойтись WCHAR* ?
Дело в том, что при копировании wchar* строки копирование производится только до 0-символа, тогда как для BSTR система знает точную длину буфера. А в упакованном объекте запросто может быть последовательность нулевых байт.
Re[7]: Передача BSTR в ActiveX компонент на VC++ 6
Здравствуйте, Кодт, Вы писали:
К>Длина BSTR хранится не в первом элементе, а по смещению -4. Начиная со смещения 0 идёт обычная юникодная строка с 0 на конце.
Если быть педантом, то BSTR допускает наличие нулей и в середине строки.
\/\/i||i
Re[8]: Передача BSTR в ActiveX компонент на VC++ 6
Здравствуйте, 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
Здравствуйте, 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
Здравствуйте, Willi, Вы писали:
W>Здравствуйте, Кодт, Вы писали:
К>>Длина BSTR хранится не в первом элементе, а по смещению -4. Начиная со смещения 0 идёт обычная юникодная строка с 0 на конце.
W>Если быть педантом, то BSTR допускает наличие нулей и в середине строки.