Должна ли быть разница между пустым BSTR и NULL BSTR? - PullRequest
9 голосов
/ 05 октября 2008

При сохранении интерфейса COM следует ли обрабатывать пустой BSTR так же, как NULL? Другими словами, должны ли эти два вызова функций давать одинаковый результат?

 // Empty BSTR
 CComBSTR empty(L""); // Or SysAllocString(L"")
 someObj->Foo(empty);

 // NULL BSTR
 someObj->Foo(NULL);     

Ответы [ 2 ]

14 голосов
/ 05 октября 2008

Да - NULL BSTR совпадает с пустым. Я помню, у нас были всевозможные ошибки, которые были обнаружены при переходе с VS6 на 2003 - класс CComBSTR изменил конструктор по умолчанию, который выделил его с использованием NULL, а не пустой строки. Это происходит, когда вы, например, рассматриваете BSTR как обычную строку в стиле C и передаете ее какой-либо функции, например strlen, или пытаетесь инициализировать std::string с ней.

Эрик Липперт подробно описывает BSTR в Полное руководство Эрика по семантике BSTR :

Позвольте мне сначала перечислить различия и затем обсудите каждый пункт мучительная деталь.

1) BSTR должен иметь идентичный семантика для NULL и для "". PWSZ часто имеет различную семантику те.

2) BSTR должен быть выделен и освобожден с семейством SysAlloc * функции. PWSZ может быть буфер автоматического хранения из стек или выделенный с помощью malloc, new, LocalAlloc или любая другая память Распределитель.

3) BSTR имеет фиксированную длину. PWSZ может иметь любую длину, ограниченную только количество действительной памяти в его буфер.

4) BSTR всегда указывает на первый допустимый символ в буфере. PWSZ может быть указателем на середину или конец строкового буфера.

5) При выделении n-байтового BSTR вы есть место для n / 2 широких символов. Когда вы выделяете n байтов для PWSZ Вы можете хранить n / 2 - 1 символов - Вы должны оставить место для нуля.

6) BSTR может содержать любые данные Unicode включая нулевой символ. PWSZ никогда не содержит нулевой символ кроме как маркер конца строки. И BSTR, и PWSZ всегда имеют нулевой символ после их последнего действительного характер, но в BSTR действительный символ может быть нулевым.

7) BSTR может содержать нечетное число количество байтов - может использоваться для перемещение двоичных данных. PWSZ это почти всегда четное количество байтов и используется только для хранения Unicode строки.

4 голосов
/ 05 октября 2008

Самый простой способ справиться с этой дилеммой - использовать CComBSTR и проверить, что .Length () равен нулю. Это работает как для пустых, так и для пустых значений.

Однако имейте в виду, пустой BSTR должен быть освобожден, иначе произойдет утечка памяти. Я видел некоторые из них недавно в коде другого. Довольно трудно найти, если вы не смотрите внимательно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...