我从网络上的蓝牙示例中获得了一段代码,我们使用了一个条件:
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&#39; :无法转换参数1来自&#39; LPSTR&#39; to&#39; const wchar_t *&#39;
这显然不起作用,因为我不使用Unicode而是使用Multi Byte字符集。您建议将pWSAQuerySet->lpszServiceInstanceName
转换为wchar
,以便将苹果与苹果进行比较?
答案 0 :(得分:0)
_wcsicmp_l()
需要两个wchar_t
字符串,但是您在第一个参数中传递char
字符串,因此出错。这意味着pWSAQuerySet
指向的是WSAQUERYSETA
,而不是WSAQUERYSETW
。由于您的代码使用基于TCHAR
的{{1}},这意味着您的项目设置为MBCS而不是Unicode。
如果WSAQUERYSET
是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
。您不必将整个项目更改为Unicode以使用Unicode API。只需停止使用基于char
的API并直接使用Unicode API(就像使用TCHAR
而不是wprintf()
一样)。在这种情况下,请直接使用printf()
和WSALookupServiceBeginW()
,例如:
WSALookupServiceNextW()