wprintf(L"Selecting Audio Input Device: %s\n",
varName.bstrVal);
if(0 == strcmp(varName.bstrVal, "IP Camera [JPEG/MJPEG]"))...
以上报告:
error C2664: 'strcmp' : cannot convert parameter 1 from 'BSTR' to 'const char *'
你需要使用wcscmp
代替:
if(0 == wcscmp(varName.bstrVal, L"IP Camera [JPEG/MJPEG]"))
{
}
这里是BSTR数据类型的描述,它包含一个长度前缀和一个实际的字符串部分,其中只是一串WCHAR字符数组。此外,它还有两个NULL终止符。
需要注意的是BSTR数据类型的字符串部分可以包含嵌入的NULL值,因此wcscmp
仅在BSTR不包含嵌入的NULL值的情况下工作(这可能是大多数情况)。
这里的所有其他答案要么完全错误,要么部分不正确,因为它们忽略了 BSTR
和 std::wstring
都可以包含多个嵌入的空字符。
这意味着它们不应该使用 wcscmp()
进行比较,因为它会在任一字符串中遇到第一个 \0
时停止比较。
以下是正确比较 BSTR
和 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;
}
_wcsnicmp()
进行不区分大小写的比较,否则示例将打印“字符串不相等”。我的解决方案:
static const std::wstring IPCamera = L"IP Camera [JPEG/MJPEG]";
if (varName.bstrVal == IPCamera {
//...
我总是在BSTR周围构建_bstr_t
包装器。这使得事情变得更加容易和符合惯用法:
if(std::string("IP Camera [JPEG/MJPEG]") ==
static_cast<const char*>( _bstr_t(varName.bstrVal) )
{
}
w
,而有些是wc
? - COMer