com string bstr

com - ¿Debería haber una diferencia entre un BSTR vacío y un BSTR NULL?



string (2)

Al mantener una interfaz COM , ¿debería tratarse un BSTR vacío de la misma manera que NULL ? En otras palabras, ¿estas dos llamadas a función producen el mismo resultado?

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


La forma más fácil de manejar este dilema es usar CComBSTR y verificar que .Length () sea cero. Eso funciona para valores vacíos y NULOS.

Sin embargo, tenga en cuenta que se debe liberar BSTR vacío o habrá una pérdida de memoria. Vi algunos de ellos recientemente en el código de otros. Bastante difícil de encontrar, si no estás mirando con cuidado.


Sí, un BSTR NULO es lo mismo que uno vacío. Recuerdo que teníamos todo tipo de errores que se descubrieron cuando cambiamos de VS6 a 2003: la clase CComBSTR tenía un cambio en el constructor predeterminado que lo asignaba usando NULL en lugar de una cadena vacía. Esto sucede cuando, por ejemplo, se trata un BSTR como una cadena de estilo C normal y se pasa a alguna función como strlen , o se intenta inicializar una std::string con ella.

Eric Lippert discute los BSTR con gran detalle en la Guía Completa de Eric para Semántica BSTR :

Permítanme enumerar las diferencias primero y luego discutir cada punto con detalles insoportables.

1) Un BSTR debe tener una semántica idéntica para NULL y para "". Un PWSZ frecuentemente tiene una semántica diferente para esos.

2) Un BSTR debe asignarse y liberarse con la familia de funciones SysAlloc *. Un PWSZ puede ser un búfer de almacenamiento automático de la pila o asignado con malloc, nuevo LocalAlloc o cualquier otro asignador de memoria.

3) Un BSTR es de longitud fija. Un PWSZ puede tener cualquier longitud, limitado solo por la cantidad de memoria válida en su memoria intermedia.

4) Un BSTR siempre apunta al primer carácter válido en el búfer. Un PWSZ puede ser un puntero al medio o al final de un buffer de cadena.

5) Al asignar un BSTR n-byte, tiene espacio para n / 2 caracteres anchos. Cuando asigna n bytes para un PWSZ puede almacenar n / 2 - 1 caracteres; debe dejar espacio para el nulo.

6) Un BSTR puede contener datos Unicode incluyendo el carácter cero. Un PWSZ nunca contiene el carácter cero excepto como un marcador de fin de cadena. Tanto un BSTR como un PWSZ siempre tienen un carácter cero después de su último carácter válido, pero en un BSTR un carácter válido puede ser cero.

7) Un BSTR en realidad puede contener un número impar de bytes: se puede usar para mover datos binarios. Un PWSZ es casi siempre un número par de bytes y se usa solo para almacenar cadenas Unicode.