-1

条件を使用する Web 上の 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() を適切に使用するのを手伝ってもらえますか? 前もって感謝します!

4

1 に答える 1

0

_wcsicmp_l()2 つの文字列が必要ですが、最初のパラメーターで文字列wchar_tを渡しているため、エラーが発生します。charこれは、 ではなく をpWSAQuerySet指していることを意味します。あなたのコードは-basedを使用しているため、プロジェクトが Unicode ではなく MBCS に設定されていることを意味します。WSAQUERYSETAWSAQUERYSETWTCHARWSAQUERYSET

pszRemoteNameが文字列の場合wchar_t、それを文字列と比較することはできませんchar。それらは完全に異なるデータ型です。それらの 1 つを他のものに変換する必要があります。この場合、lpszServiceInstanceName値をwchar_tusingMultiByteToWideChar()または equivilent に変換する必要があります。次に、変換された値を と比較できます。次に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代わりに使用するように変更することです。Unicode API を使用するために、プロジェクト全体を Unicode に変更する必要はありません。ベースの API の使用をやめて、Unicode API を直接使用してください (の代わりに使用しているように)。この場合、and を直接使用します。例:WSAQUERYSETAlpszServiceInstanceNamewchar_tcharTCHARwprintf()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;
}
于 2016-09-26T14:47:47.037 に答える