Sollte es einen Unterschied zwischen einem leeren BSTR sein und eine NULL BSTR?
Frage
Wenn Sie eine COM
Schnittstelle beibehalten sollte ein leerer BSTR
die gleiche Art und Weise wie NULL
behandelt werden?
Mit anderen Worten sollten diese beiden Funktionsaufrufe erzeugen das gleiche Ergebnis?
// Empty BSTR
CComBSTR empty(L""); // Or SysAllocString(L"")
someObj->Foo(empty);
// NULL BSTR
someObj->Foo(NULL);
Lösung
Ja - ein NULL BSTR ist das gleiche wie ein leeres. Ich erinnere mich, wir alle möglichen Fehler hatte, die aufgedeckt wurden, als wir von VS6 bis 2003 eingeschaltet - die CComBSTR Klasse für eine Änderung des Standard-Konstruktor hatte, dass es NULL lieber als eine leere Zeichenfolge mit zugeordnet. Dies geschieht, wenn Sie zum Beispiel eines BSTR als reguläres CStrings behandeln und es bis zu einem gewissen Funktion wie strlen
passieren, oder versuchen, eine std::string
mit ihm zu initialisieren.
Eric Lippert diskutiert BSTR ist im Detail in Erics Complete Guide To BSTR Semantics :
Lassen Sie mich die Unterschiede Liste zuerst und diskutieren dann jeden Punkt quälendes Detail.
1) Ein BSTR müssen identische Semantik für NULL und für „“. Ein PWSZ häufig hat unterschiedliche Semantik für diejenigen.
2) Ein BSTR muss zugewiesen und freigegeben werden mit der SysAlloc * Familie Funktionen. Ein PWSZ kann eine sein Automatik-Speicherpuffer aus dem stapeln oder mit malloc, neu, LocalAlloc oder jeder anderer Speicher Allocator.
3) Ein BSTR ist fester Länge. Ein PWSZ kann von beliebiger Länge sein, begrenzt nur durch die Menge der gültigen Speicher in seinen Puffer.
4) Ein BSTR zeigt immer auf den ersten gültiges Zeichen in dem Puffer. Ein PWSZ kann ein Zeiger auf die Mitte oder Ende ein String-Puffer.
5) Bei der Zuordnung eines n-Byte BSTR Sie hat Platz für n / 2 breite Zeichen. Wenn Sie n zuteilen Bytes für einen PWSZ 1 Zeichen - Sie können n / 2 speichern - Sie haben Platz für die Null zu verlassen.
6) A BSTR beliebige Unicode-Daten enthalten kann, einschließlich des Null-Zeichen. Ein PWSZ nie enthält die Nullzeichen außer als End-of-String-Marker. Sowohl ein BSTR und ein PWSZ haben immer eine Nullzeichen nach dem letzten gültigen Charakter, aber in einem BSTR einer gültigen Zeichen kann ein Nullzeichen sein.
7) Ein BSTR enthalten kann tatsächlich eine ungerade Anzahl von Bytes - es kann verwendet werden, binäre Daten bewegen. Ein PWSZ ist fast immer eine gerade Anzahl von Bytes und nur zum Speichern von Unicode verwendet Strings.
Andere Tipps
Der einfachste Weg, dieses Dilemma zu umgehen ist CComBSTR zu verwenden und prüfen, ob .Length () Null. Das funktioniert für beide leer und NULL-Werte.
Doch bedenken Sie, leeren BSTR freigegeben werden müssen, oder es wird ein Speicherverlust sein. Vor kurzem sah ich einige von denen in anderen Code. Ganz schwer zu finden, wenn Sie nicht sorgfältig suchen sind.