2008-10-05 11 views

Respuesta

13

Sí - a NULL BSTR 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 un std::string con ella.

Eric Lippert discute BSTR de gran detalle en Eric's Complete Guide To BSTR Semantics:

Permítanme enumerar las diferencias primera y luego discutir cada punto en absoluto detalle.

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

2) Se debe asignar y liberar un BSTR con la familia SysAlloc * de las funciones . Un PWSZ puede ser un almacenamiento intermedio de almacenamiento automático de la pila o asignado con malloc, nuevo, localAlloc o cualquier otra memoria asignador.

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 centro o al final de un búfer de cadena.

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

6) Un BSTR puede contener cualquier dato Unicode incluyendo el carácter cero. Un PWSZ nunca contiene el carácter cero excepto como 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 tener cero caracteres.

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

+4

En la mano de agarre --- He experimentado el código MSXML que no obedece a la regla NULL == empty, y muestra un comportamiento diferente para los dos. Pero eso fue hace 5 años (MSXML 3, si mal no recuerdo), y con suerte ya lo arreglaron. :-) –

+2

. Las interpolaciones .NET tampoco obedecen las reglas: marcan "" a String.Empty y NULL a null. –

4

La manera 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.

Cuestiones relacionadas