All other answers here are either outright wrong or partially incorrect because they are ignoring the fact that both BSTR
and std::wstring
can contain multiple embedded null characters.
That means they should not be compared using wcscmp()
, which will stop comparison on the first \0
it encounters in either string.
Here is how to properly compare BSTR
with std::wstring
:
// Windows.h defines min() and max() as macros
#define NOMINMAX
#include <Windows.h>
#include <string>
// std::string_literals namespace requires C++14,
// but it is needed only to construct strings with
// embedded nulls, not for the comparison itself
using namespace std::string_literals;
int wmain(int argc, wchar_t *argv[])
{
std::wstring String1 = L"I am a happy BSTR \0with \0embedded \0null chars"s;
std::wstring Temp = L"I am a happy bstr \0with \0embedded \0NULL chars"s;
BSTR String2 = SysAllocStringLen(Temp.c_str(), Temp.size());
if (String2 == nullptr) {
return ERROR_OUTOFMEMORY;
}
// make sure not to create a security vulnerability by
// reading past the end of either buffer when comparing
const size_t MaxCount = std::min(String1.size(), static_cast<size_t>(SysStringLen(String2)));
bool Equal = wcsncmp(String1.c_str(), String2, MaxCount) == 0;
if (Equal) {
wprintf(L"Strings are equal\n");
} else {
wprintf(L"Strings are NOT equal\n");
}
SysFreeString(String2);
return 0;
}
Note that the example will print "Strings are NOT equal" unless you change it to use _wcsnicmp()
for case-insensitive comparison.
w
while some arewc
? – Monomania