无法从lpstr转换为wchar_t

时间:2016-09-26 14:36:38

标签: c++ bluetooth wchar-t lpstr

我从网络上的蓝牙示例中获得了一段代码,我们使用了一个条件:

 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,以便将苹果与苹果进行比较?

谷歌搜索错误对我没什么帮助,我担心我不太了解它。 你能帮我正确使用int MultiByteToWideChar()吗?提前谢谢!

1 个答案:

答案 0 :(得分:0)

_wcsicmp_l()需要两个wchar_t字符串,但是您在第一个参数中传递char字符串,因此出错。这意味着pWSAQuerySet指向的是WSAQUERYSETA,而不是WSAQUERYSETW。由于您的代码使用基于TCHAR的{​​{1}},这意味着您的项目设置为MBCS而不是Unicode。

如果WSAQUERYSETpszRemoteName字符串,则无法将其与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()