繁体   English   中英

无法从 lpstr 转换为 wchar_t

[英]Cannot convert from lpstr to wchar_t

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

 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() 吗? 先感谢您!

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

如果pszRemoteNamewchar_t字符串,则无法将其与char字符串进行比较。 它们是完全不同的数据类型。 其中一个必须转换为另一个。 在这种情况下,您应该使用MultiByteToWideChar()或等效方法将lpszServiceInstanceName值转换为wchar_t ,然后您可以将转换后的值与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。 只需停止使用基于TCHAR的 API 并直接使用 Unicode API(就像您使用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;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM