簡體   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