Не могу конвертировать из lpstr в wchar_t

Я получил фрагмент кода из примера Bluetooth в Интернете, где мы используем условие:

 ULONG NameToBthAddr(_In_ const LPWSTR pszRemoteName, _Out_ PSOCKADDR_BTH pRemoteBtAddr)
{
INT             iResult = CXN_SUCCESS;
BOOL            bContinueLookup = FALSE, bRemoteDeviceFound = FALSE;
ULONG           ulFlags = 0, ulPQSSize = sizeof(WSAQUERYSET);
HANDLE          hLookup = NULL;
PWSAQUERYSET    pWSAQuerySet = NULL;

ZeroMemory(pRemoteBtAddr, sizeof(*pRemoteBtAddr));

pWSAQuerySet = (PWSAQUERYSET)HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
ulPQSSize);
if (NULL ==
) {
iResult = STATUS_NO_MEMORY;
wprintf(L"!ERROR! | Unable to allocate memory for WSAQUERYSET\n");
}

//
// Search for the device with the correct name
//
if (CXN_SUCCESS == iResult) {

for (INT iRetryCount = 0;
!bRemoteDeviceFound && (iRetryCount < CXN_MAX_INQUIRY_RETRY);
iRetryCount++) {
//
// WSALookupService is used for both service search and device inquiry
// LUP_CONTAINERS is the flag which signals that we're doing a device inquiry.
//
ulFlags = LUP_CONTAINERS;

//
// Friendly device name (if available) will be returned in lpszServiceInstanceName
//
ulFlags |= LUP_RETURN_NAME;

//
// BTH_ADDR will be returned in lpcsaBuffer member of WSAQUERYSET
//
ulFlags |= LUP_RETURN_ADDR;

if (0 == iRetryCount) {
wprintf(L"*INFO* | Inquiring device from cache...\n");
}
else {
//
// Flush the device cache for all inquiries, except for the first inquiry
//
// By setting LUP_FLUSHCACHE flag, we're asking the lookup service to do
// a fresh lookup instead of pulling the information from device cache.
//
ulFlags |= LUP_FLUSHCACHE;

//
// Pause for some time before all the inquiries after the first inquiry
//
// Remote Name requests will arrive after device inquiry has
// completed.  Without a window to receive IN_RANGE notifications,
// we don't have a direct mechanism to determine when remote
// name requests have completed.
//
wprintf(L"*INFO* | Unable to find device.  Waiting for %d seconds before re-inquiry...\n", CXN_DELAY_NEXT_INQUIRY);
Sleep(CXN_DELAY_NEXT_INQUIRY * 1000);

wprintf(L"*INFO* | Inquiring device ...\n");
}

//
// Start the lookup service
//
iResult = CXN_SUCCESS;
hLookup = 0;
bContinueLookup = FALSE;
ZeroMemory(pWSAQuerySet, ulPQSSize);
pWSAQuerySet->dwNameSpace = NS_BTH;
pWSAQuerySet->dwSize = sizeof(WSAQUERYSET);
iResult = WSALookupServiceBegin(pWSAQuerySet, ulFlags, &hLookup);

//
// Even if we have an error, we want to continue until we
// reach the CXN_MAX_INQUIRY_RETRY
//
if ((NO_ERROR == iResult) && (NULL != hLookup)) {
bContinueLookup = TRUE;
}
else if (0 < iRetryCount) {
wprintf(L"=CRITICAL= | WSALookupServiceBegin() failed with error code %d, WSAGetLastError = %d\n", iResult, WSAGetLastError());
break;
}

while (bContinueLookup) {
//
// Get information about next bluetooth device
//
// Note you may pass the same WSAQUERYSET from LookupBegin
// as long as you don't need to modify any of the pointer
// members of the structure, etc.
//
// ZeroMemory(pWSAQuerySet, ulPQSSize);
// pWSAQuerySet->dwNameSpace = NS_BTH;
// pWSAQuerySet->dwSize = sizeof(WSAQUERYSET);
if (NO_ERROR == WSALookupServiceNext(hLookup,
ulFlags,
&ulPQSSize,
pWSAQuerySet)) {

//
// Compare the name to see if this is the device we are looking for.
//

if ((pWSAQuerySet->lpszServiceInstanceName != NULL) &&
(CXN_SUCCESS == _wcsicmp_l(pWSAQuerySet->lpszServiceInstanceName, pszRemoteName))) {
}
}

Теперь lpszServiceInstancename определено в winSock2.h, где я вижу:

#ifdef UNICODE
typedef WSAQUERYSETW WSAQUERYSET;
typedef PWSAQUERYSETW PWSAQUERYSET;
typedef LPWSAQUERYSETW LPWSAQUERYSET;
typedef WSAQUERYSET2W WSAQUERYSET2;
typedef PWSAQUERYSET2W PWSAQUERYSET2;
typedef LPWSAQUERYSET2W LPWSAQUERYSET2;
#else
typedef WSAQUERYSETA WSAQUERYSET;
typedef PWSAQUERYSETA PWSAQUERYSET;
typedef LPWSAQUERYSETA LPWSAQUERYSET;
typedef WSAQUERYSET2A WSAQUERYSET2;
typedef PWSAQUERYSET2A PWSAQUERYSET2;
typedef LPWSAQUERYSET2A LPWSAQUERYSET2;
#endif /* UNICODE */typedef struct _WSAQuerySetA
{
DWORD           dwSize;
LPSTR           lpszServiceInstanceName;
LPGUID          lpServiceClassId;
LPWSAVERSION    lpVersion;
LPSTR           lpszComment;
DWORD           dwNameSpace;
LPGUID          lpNSProviderId;
LPSTR           lpszContext;
DWORD           dwNumberOfProtocols;
__field_ecount(dwNumberOfProtocols) LPAFPROTOCOLS   lpafpProtocols;
LPSTR           lpszQueryString;
DWORD           dwNumberOfCsAddrs;
__field_ecount(dwNumberOfCsAddrs) LPCSADDR_INFO   lpcsaBuffer;
DWORD           dwOutputFlags;
LPBLOB          lpBlob;
} WSAQUERYSETA, *PWSAQUERYSETA, *LPWSAQUERYSETA;
typedef __struct_bcount(dwSize) struct _WSAQuerySetW
{
DWORD           dwSize;
LPWSTR          lpszServiceInstanceName;
LPGUID          lpServiceClassId;
LPWSAVERSION    lpVersion;
LPWSTR          lpszComment;
DWORD           dwNameSpace;
LPGUID          lpNSProviderId;
LPWSTR          lpszContext;
DWORD           dwNumberOfProtocols;
__field_ecount(dwNumberOfProtocols) LPAFPROTOCOLS   lpafpProtocols;
LPWSTR          lpszQueryString;
DWORD           dwNumberOfCsAddrs;
__field_ecount(dwNumberOfCsAddrs) LPCSADDR_INFO   lpcsaBuffer;
DWORD           dwOutputFlags;
LPBLOB          lpBlob;
} WSAQUERYSETW, *PWSAQUERYSETW, *LPWSAQUERYSETW;

Однако я получаю ошибку:

_wcsicmp ‘: невозможно преобразовать параметр 1 из’ LPSTR ‘в’ const wchar_t * ‘

Это, очевидно, не работает, потому что я не использую Unicode, но многобайтовый набор символов. Что бы вы посоветовали конвертировать pWSAQuerySet->lpszServiceInstanceName в wchar чтобы я сравнивал яблоки с яблоками?

Погуглить ошибку мне не очень помогло, боюсь, я ее плохо понимаю.
Можете ли вы помочь мне правильно использовать int MultiByteToWideChar ()? Заранее спасибо!

-1

Решение

_wcsicmp_l() ожидает двух wchar_t строки, но вы передаете char строка в первом параметре, следовательно, ошибка. Что значит pWSAQuerySet указывает на WSAQUERYSETA и не WSAQUERYSETW, Поскольку ваш код использует TCHAR-основан WSAQUERYSETЭто означает, что ваш проект настроен на MBCS, а не на Unicode.

Если pszRemoteName это wchar_t строка, то вы не можете сравнить его с char строка. Это совершенно разные типы данных. Один из них должен быть преобразован в другой. В этом случае вам следует преобразовать lpszServiceInstanceName значение для wchar_t с помощью MultiByteToWideChar() или эквивалентный, то вы можете сравнить преобразованное значение с pszRemoteNameНапример:

int len = MultiByteToWideChar(CP_ACP, 0, pWSAQuerySet->lpszServiceInstanceName, -1, NULL, 0);
if (len > 0) {
wchar_t *pszServiceInstanceName = new wchar_t[len];
MultiByteToWideChar(CP_ACP, 0, pWSAQuerySet->lpszServiceInstanceName, -1, pszServiceInstanceName, len);
if (CXN_SUCCESS == _wcsicmp_l(pszServiceInstanceName, pszRemoteName) {
//...
}
delete[] pszServiceInstanceName;
}

Альтернатива состоит в том, чтобы изменить код для использования WSAQUERYSETW вместо WSAQUERYSETA так что его lpszServiceInstanceName полевые использования wchar_t вместо char, Вам не нужно менять весь проект на Unicode, чтобы использовать API Unicode. Просто прекратите использовать TCHARAPI-интерфейсы и использовать API-интерфейсы Unicode напрямую (так же, как вы используете wprintf() вместо printf()). В этом случае используйте WSALookupServiceBeginW() а также WSALookupServiceNextW() напрямую, например:

BOOL NameToBthAddr(_In_ LPCWSTR pszRemoteName, _Out_ PSOCKADDR_BTH pRemoteBtAddr)
{
INT             iResult;
BOOL            bContinueLookup = TRUE, bRemoteDeviceFound = FALSE;
ULONG           ulFlags = 0, ulPQSSize = sizeof(WSAQUERYSETW);
HANDLE          hLookup = NULL;
PWSAQUERYSETW   pWSAQuerySet = NULL;

ZeroMemory(pRemoteBtAddr, sizeof(*pRemoteBtAddr));

pWSAQuerySet = (PWSAQUERYSETW) HeapAlloc(GetProcessHeap(), 0, ulPQSSize);
if (!pWSAQuerySet) {
wprintf(L"!ERROR! | Unable to allocate memory for WSAQUERYSET\n");
return FALSE;
}

//
// Search for the device with the correct name
//

for (int iRetryCount = 0; (!bRemoteDeviceFound) && (iRetryCount < CXN_MAX_INQUIRY_RETRY) && (bContinueLookup); ++iRetryCount) {
//
// WSALookupService is used for both service search and device inquiry
// LUP_CONTAINERS is the flag which signals that we're doing a device inquiry.
//
ulFlags = LUP_CONTAINERS;

//
// Friendly device name (if available) will be returned in lpszServiceInstanceName
//
ulFlags |= LUP_RETURN_NAME;

//
// BTH_ADDR will be returned in lpcsaBuffer member of WSAQUERYSET
//
ulFlags |= LUP_RETURN_ADDR;

if (0 == iRetryCount) {
wprintf(L"*INFO* | Inquiring device from cache...\n");
}
else {
//
// Flush the device cache for all inquiries, except for the first inquiry
//
// By setting LUP_FLUSHCACHE flag, we're asking the lookup service to do
// a fresh lookup instead of pulling the information from device cache.
//
ulFlags |= LUP_FLUSHCACHE;

//
// Pause for some time before all the inquiries after the first inquiry
//
// Remote Name requests will arrive after device inquiry has
// completed.  Without a window to receive IN_RANGE notifications,
// we don't have a direct mechanism to determine when remote
// name requests have completed.
//
wprintf(L"*INFO* | Unable to find device.  Waiting for %d seconds before re-inquiry...\n", CXN_DELAY_NEXT_INQUIRY);
Sleep(CXN_DELAY_NEXT_INQUIRY * 1000);

wprintf(L"*INFO* | Inquiring device ...\n");
}

//
// Start the lookup service
//
hLookup = NULL;
ZeroMemory(pWSAQuerySet, ulPQSSize);
pWSAQuerySet->dwNameSpace = NS_BTH;
pWSAQuerySet->dwSize = ulPQSSize;

iResult = WSALookupServiceBeginW(pWSAQuerySet, ulFlags, &hLookup);
if (SOCKET_ERROR == iResult) {
wprintf(L"=CRITICAL= | WSALookupServiceBegin() failed with error code %d\n", WSAGetLastError());
break;
}

do {
//
// Get information about next bluetooth device
//
// Note you may pass the same WSAQUERYSET from LookupBegin
// as long as you don't need to modify any of the pointer
// members of the structure, etc.
//
// ZeroMemory(pWSAQuerySet, ulPQSSize);
// pWSAQuerySet->dwNameSpace = NS_BTH;
// pWSAQuerySet->dwSize = ulPQSSize;

do {
iResult = WSALookupServiceNextW(hLookup, ulFlags, &ulPQSSize, pWSAQuerySet);
if (SOCKET_ERROR != iResult) {
break;
}

iResult = WSAGetLastError();
if (WSAEFAULT != iResult) {
break;
}

PWSAQUERYSETW pNewWSAQuerySet = (PWSAQUERYSETW) HeapReAlloc(GetProcessHeap(), 0, pWSAQuerySet, ulPQSSize);
if (!pNewWSAQuerySet) {
wprintf(L"!ERROR! | Unable to re-allocate memory for WSAQUERYSET\n");
iResult = WSA_NOT_ENOUGH_MEMORY;
break;
}

pWSAQuerySet = pNewWSAQuerySet;
}
while (true);

if (NO_ERROR != iResult) {
if (WSA_E_NO_MORE != iResult) {
bContinueLookup = FALSE;
}
break;
}

//
// Compare the name to see if this is the device we are looking for.
//

if ((pWSAQuerySet->lpszServiceInstanceName) && (0 == _wcsicmp_l(pWSAQuerySet->lpszServiceInstanceName, pszRemoteName))) {
bRemoteDeviceFound = TRUE;
CopyMemory(pRemoteBtAddr, pWSAQuerySet->lpcsaBuffer->RemoteAddr.lpSockaddr, sizeof(*pRemoteBtAddr));
break;
}
}
while (true);

WSALookupServiceEnd(hLookup);
}

HeapFree(GetProcessHeap(), 0, pWSAQuerySet);

return bRemoteDeviceFound;
}
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]