Meilleures pratiques relatives à l’API haut débit mobile
Lorsque vous utilisez l’API Haut débit mobile, l’ensemble de bonnes pratiques suivant doit être utilisé afin d’obtenir les meilleures performances possibles.
Ne pas mettre en cache les objets fonctionnels
Les objets fonctionnels, tels que IMbnInterface et d’autres, sont obtenus à partir d’objets de gestionnaire, comme IMbnInterfaceManager, à l’aide de la méthode d’énumération sur l’objet de gestionnaire correspondant. Ne mettez pas en cache ces objets fonctionnels, car les objets fonctionnels mis en cache contiennent des données obsolètes. Les opérations synchrones effectuées sur ces objets fonctionnels retournent les mêmes données jusqu’à ce que les objets fonctionnels soient à nouveau obtenus.
Au lieu de cela, mettez en cache les objets de gestionnaire et récupérez les objets fonctionnels à partir de l’objet manager à l’aide de la méthode d’énumération sur l’objet de gestionnaire correspondant pour obtenir les données les plus récentes.
L’exemple de code suivant montre comment mettre en cache les objets du gestionnaire.
#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;
}
Gérer toutes les notifications
Suivez et gérez toutes les notifications, même si elles ne sont pas déclenchées par votre application. Cela est nécessaire pour maintenir la synchronisation de l’interface utilisateur avec l’état réel de l’appareil.
Plusieurs gestionnaires de connexions peuvent être exécutés sur un ordinateur. L’interface utilisateur d’interface réseau disponible d’affichage native fournie par Windows 7 est un gestionnaire de connexions. Tous les autres gestionnaires de connexions doivent répondre à toutes les notifications pour rester synchronisés avec l’interface utilisateur windows native. Un utilisateur peut choisir d’effectuer une opération sur l’un des gestionnaires de connexions, ce qui peut entraîner un changement d’état de l’appareil haut débit mobile. Toutefois, d’autres gestionnaires de connexions doivent rester à jour afin d’indiquer correctement l’état modifié de l’appareil.
Par exemple, l’exécution d’une connexion à l’aide de l’un des gestionnaires de connexions modifie l’état de l’appareil de disponible à connecté. Cette modification doit être visible pour les gestionnaires de connexions qui n’ont pas lancé cette action. Tous les gestionnaires de connexions dont l’interface utilisateur indique l’état de connexion de l’appareil doivent écouter et gérer les notifications d’état de connexion afin de mettre à jour correctement leur interface utilisateur.
Envoi et réception d’octets
Utilisez les fonctions d’assistance IP GetlfEntry et GetlfEntry2 pour envoyer et recevoir des octets.
Utilisation de l’API Deblock pin
Une application cliente appelante doit être élevée pour pouvoir appeler IMbnPin::Unblock. Cette méthode est la seule partie de l’API Haut débit mobile qui nécessite des privilèges d’administrateur ou de NCO.
Utilisation de SafeArrays
Utilisez ZeroMemory() avant d’accéder aux éléments d’un SafeArray.
Ne case activée pas sur les index d’un SafeArray. Ils peuvent être négatifs.
L’exemple de code suivant montre comment gérer correctement un 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();
}