다음을 통해 공유


모바일 광대역 API 모범 사례

모바일 광대역 API를 사용할 때 최상의 성능을 얻으려면 다음 모범 사례 집합을 사용해야 합니다.

기능 개체 캐시 안 함

IMbnInterface 등의 기능 개체는 해당 관리자 개체의 열거형 메서드를 사용하여 IMbnInterfaceManager와 같은 관리자 개체에서 가져옵니다. 캐시된 기능 개체에 부실 데이터가 포함되어 있으므로 이러한 기능 개체를 캐시하지 마세요. 이러한 기능 개체에서 수행되는 동기 작업은 기능 개체를 다시 가져올 때까지 동일한 데이터를 반환합니다.

대신, 관리자 개체를 캐시하고 해당 관리자 개체의 열거형 메서드를 사용하여 관리자 개체에서 기능 개체를 다시 가져와서 최신 데이터를 가져옵니다.

다음 코드 예제에서는 관리자 개체를 캐시하는 적절한 방법을 보여 줍니다.

#include <atlbase.h>
#include "mbnapi.h"
#include <tchar.h>

int main()
{
    HRESULT hr = E_FAIL;
    int returnVal = 0;

    do
    {
        hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);    
        if (FAILED(hr))
        {
            returnVal = hr; 
            break;
        }

        CComPtr<IMbnInterfaceManager>  g_InterfaceMgr = NULL;

        //Do the below once(cache the manager objects)
        hr = CoCreateInstance(CLSID_MbnInterfaceManager,
            NULL, 
            CLSCTX_ALL, 
            IID_IMbnInterfaceManager, 
            (void**)&g_InterfaceMgr);
        if (FAILED(hr))
        {
            returnVal = hr; 
            break;
        }

        SAFEARRAY *psa = NULL;

        //Do the below each time(do not cache functional objects)
        hr = g_InterfaceMgr->GetInterfaces(&psa);
        if (FAILED(hr))
        {
            returnVal = hr; 
            break;
        }

        LONG lLower;
        LONG lUpper;

        hr = SafeArrayGetLBound(psa, 1, &lLower);
        if (FAILED(hr))
        {
            returnVal = hr; 
            break;
        }

        hr = SafeArrayGetUBound(psa, 1, &lUpper);
        if (FAILED(hr))
        {
            returnVal = hr; 
            break;
        }

        CComPtr<IMbnInterface>  pInf = NULL;
        MBN_READY_STATE readyState;

        for (LONG l = lLower; l <= lUpper; l++)
        {
            hr = SafeArrayGetElement(psa, &l, (void*)(&pInf));
            if (FAILED(hr))
            {
                returnVal = hr; 
                break;
            }

            hr = pInf->GetReadyState(&readyState);
            if (FAILED(hr))
            {
                returnVal = hr; 
                break;
            }

            _tprintf(_T("Ready State = %d"), readyState); 
        }

        if (FAILED(hr))
        {
            break;
        }
    } while (FALSE);


    CoUninitialize();
    return returnVal;
}

모든 알림 처리

애플리케이션에 의해 트리거되지 않더라도 모든 알림을 따라 처리합니다. 이는 UI를 디바이스의 실제 상태와 동기화된 상태로 유지하는 데 필요합니다.

컴퓨터에서 실행되는 연결 관리자가 둘 이상 있을 수 있습니다. Windows 7에서 제공하는 기본 보기 사용 가능한 네트워크 인터페이스 UI는 연결 관리자입니다. 다른 모든 연결 관리자는 Windows 네이티브 UI를 동기화 상태로 유지하기 위해 모든 알림에 응답해야 합니다. 사용자는 연결 관리자 중 하나에서 일부 작업을 수행하도록 선택할 수 있으며, 이로 인해 모바일 광대역 디바이스의 상태가 변경 될 수 있습니다. 그러나 다른 연결 관리자는 디바이스의 수정된 상태를 올바르게 나타내기 위해 업데이트된 상태를 유지해야 합니다.

예를 들어 연결 관리자 중 하나를 사용하여 연결을 수행하면 디바이스 상태가 사용 가능에서 연결됨으로 변경됩니다. 이 변경 내용은 이 작업을 시작하지 않은 연결 관리자에게 표시되어야 합니다. 디바이스의 연결 상태를 나타내는 UI가 있는 모든 연결 관리자는 사용자 인터페이스를 제대로 업데이트하기 위해 연결 상태 알림을 수신 대기하고 처리해야 합니다.

바이트 보내기 및 받기

IP 도우미 함수 GetlfEntryGetlfEntry2 를 사용하여 바이트를 보내고 받습니다.

핀 차단 해제 API 사용

IMbnPin::Unblock을 성공적으로 호출하려면 호출 클라이언트 애플리케이션을 승격해야 합니다. 이 방법은 관리자 또는 NCO 권한이 필요한 모바일 광대역 API의 유일한 부분입니다.

SafeArrays 작업

  • SafeArray의 요소에 액세스하기 전에 ZeroMemory()를 사용합니다.

  • SafeArray의 인덱스에 검사 않습니다. 그들은 부정적인 수 있습니다.

다음 코드 예제에서는 SafeArray를 올바르게 처리하는 방법을 보여줍니다.

#include <atlbase.h>
#include "mbnapi.h"

void CreateVisibleProviderList(LPCWSTR interfaceID)
{
    CComPtr<IMbnInterfaceManager>  g_InterfaceMgr = NULL;
    SAFEARRAY *visibleProviders = NULL;
    long visibleLower = 0;
    long visibleUpper = 0;
    MBN_PROVIDER *pProvider = NULL;
    CComPtr<IMbnInterface> pInterface = NULL;

    HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);

    if (FAILED(hr))
    {
        goto ERROR_0;
    }

    hr = CoCreateInstance(CLSID_MbnInterfaceManager,
            NULL, 
            CLSCTX_ALL, 
            IID_IMbnInterfaceManager, 
            (void**)&g_InterfaceMgr);
    
    if (FAILED(hr))
    {
        goto ERROR_0;
    }

    hr = g_InterfaceMgr->GetInterface(interfaceID, & pInterface);
    if (FAILED(hr)) 
    {
        goto ERROR_0;
    }

    ULONG age;

    hr = pInterface->GetVisibleProviders(&age, &visibleProviders);
    if (FAILED(hr)) 
    {
        goto ERROR_0;
    }

    hr = SafeArrayGetLBound(visibleProviders, 1, &visibleLower);
    if (FAILED(hr)) 
    {
        goto ERROR_0;
    }

    hr = SafeArrayGetUBound(visibleProviders, 1, &visibleUpper);
    if (FAILED(hr)) 
    {
        goto ERROR_0;
    }

    //don't check on the indexes of safearray to be positive
    if (visibleLower > visibleUpper) 
    {
        // There are no visible providers in this case.
        hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
        goto ERROR_0;
    }

    DWORD size = (visibleUpper - visibleLower + 1) * sizeof(BOOL);
    DBG_UNREFERENCED_LOCAL_VARIABLE(size); 
    
    pProvider = (MBN_PROVIDER *)CoTaskMemAlloc(sizeof(MBN_PROVIDER));
    if (!pProvider) 
    {
        hr = E_OUTOFMEMORY;
        goto ERROR_0;
    }

    for (LONG vIndex = visibleLower; vIndex <= visibleUpper; vIndex++) 
    {
        //use zeromemory before accessing any elements in a safearray
        ZeroMemory(pProvider, sizeof(MBN_PROVIDER));
        hr = SafeArrayGetElement(visibleProviders, &vIndex, (void *)pProvider);
        if (FAILED(hr)) 
        {
            continue;
        }
    }

ERROR_0:
    if (visibleProviders) 
    {
        SafeArrayDestroy(visibleProviders);
        visibleProviders = NULL;
    }

    CoUninitialize();
}