Actions d’appel
La méthode IUPnPService::InvokeAction permet d’appeler des actions sur des objets Service. Cette méthode a deux paramètres d’entrée : le nom d’une action et un tableau d’arguments d’entrée pour cette action. La méthode a deux paramètres :
- Paramètre 1 : paramètre d’entrée/sortie : tableau d’arguments de sortie pour cette action.
- Paramètre 2 — paramètre de sortie : valeur de retour.
La méthode provoque l’appel de l’action sur l’appareil. L’appareil génère des notifications d’événements si l’action entraîne la modification des variables d’état de l’appareil.
Exemple VBScript
L’exemple de code VBScript suivant appelle deux actions sur un objet Service. La première action, GetTrackInfo, prend un argument d’entrée, un numéro de piste. L’action GetTrackInfo retourne la longueur de la piste comme valeur de retour. L’action a également un argument de sortie, qui contient le titre de la piste si la méthode retourne la réussite.
Après avoir appelé l’action GetTrackInfo , l’exemple appelle l’action Lire, qui ne prend aucun argument. Toutefois, étant donné que la syntaxe d’InvokeAction nécessite un tableau d’arguments d’entrée et de sortie, l’exemple doit créer un tableau vide, emptyArgs, sans élément. L’exemple transmet ce tableau à InvokeAction pour les arguments d’entrée et de sortie, ainsi que le nom de l’action.
Dim returnVal
Dim outArgs(1)
Dim args(1)
args(0) = 3
returnVal = service.InvokeAction("GetTrackInfo", args, outArgs)
'return Val now contains the track length
'and outArgs(0) contains the track title
Dim emptyArgs(0)
returnVal = service.InvokeAction("Play", emptyArgs, emptyArgs)
'returnVal indicates if the action was successful
Exemple C++
L’exemple suivant définit une fonction C++ qui appelle une action sans argument. Étant donné qu’InvokeAction nécessite qu’un SAFEARRAY d’arguments soit transmis, cet exemple crée un SAFEARRAY vide. Étant donné que cette action ne retourne pas de valeur ou n’a pas d’arguments de sortie, cet exemple ignore les deux dernières valeurs VARIANT passées à InvokeAction.
L’appareil génère des notifications d’événements si l’action entraîne la modification des variables d’état de l’appareil.
#include <windows.h>
#include <upnp.h>
#include <iostream>
#include <iomanip>
#pragma comment(lib, "oleaut32.lib")
using namespace std;
void InvokePlay(IUPnPService * pService)
{
HRESULT hr;
BSTR bstrActionName;
bstrActionName = SysAllocString(L"Play");
if (bstrActionName)
{
SAFEARRAYBOUND rgsaBound[1];
SAFEARRAY * psa = NULL;
rgsaBound[0].lLbound = 0;
rgsaBound[0].cElements = 0;
psa = SafeArrayCreate(VT_VARIANT, 1, rgsaBound);
if (psa)
{
LONG lStatus;
VARIANT varInArgs;
VariantInit(&varInArgs);
varInArgs.vt = VT_VARIANT | VT_ARRAY;
V_ARRAY(&varInArgs) = psa;
hr = pService->InvokeAction(bstrActionName,
varInArgs,
NULL,
NULL);
if (SUCCEEDED(hr))
{
wcout << L"Action invoked successfully\n";
}
else
{
wcerr << L"Failed to invoke action - HRESULT 0x"
<< setbase(16)
<< hr << L"\n";
}
SafeArrayDestroy(psa);
}
else
{
wcerr << L"Failed to create safe array\n";
}
SysFreeString(bstrActionName);
}
else
{
wcerr << L"Failed to allocate action name string\n";
}
}
L’exemple suivant appelle l’action GetTrackInfo fictive. Il prend un numéro de piste en tant qu’argument, retourne la longueur de la piste en tant que valeur de retour et retourne le titre de la piste dans un argument de sortie. Le code est similaire à l’exemple précédent, sauf qu’au lieu de créer une valeur SAFEARRAY vide d’arguments d’entrée, cet exemple insère un VARIANT qui contient le numéro de piste. Si InvokeAction retourne la réussite, cet exemple examine la valeur de retour et le tableau d’arguments de sortie.
#include <windows.h>
#include <upnp.h>
#include <iostream>
#include <iomanip>
#pragma comment(lib, "oleaut32.lib")
using namespace std;
void InvokeGetTrackInfo(IUPnPService * pService)
{
HRESULT hr;
BSTR bstrActionName;
bstrActionName = SysAllocString(L"GetTrackInfo");
if (bstrActionName)
{
SAFEARRAYBOUND rgsaBound[1];
SAFEARRAY * psa = NULL;
rgsaBound[0].lLbound = 0;
rgsaBound[0].cElements = 1;
psa = SafeArrayCreate(VT_VARIANT, 1, rgsaBound);
if (psa)
{
long rgIndices[1];
VARIANT varTrackNum;
rgIndices[0] = 0;
VariantInit(&varTrackNum);
varTrackNum.vt = VT_I4;
// An arbitrary track is chosen (track 3)
V_I4(&varTrackNum) = 3;
hr = SafeArrayPutElement(psa,
rgIndices,
(void *) &varTrackNum);
VariantClear(&varTrackNum);
if (SUCCEEDED(hr))
{
LONG lStatus;
VARIANT varInArgs;
VARIANT varOutArgs;
VARIANT varReturnVal;
VariantInit(&varInArgs);
VariantInit(&varOutArgs);
VariantInit(&varReturnVal);
varInArgs.vt = VT_VARIANT | VT_ARRAY;
V_ARRAY(&varInArgs) = psa;
hr = pService->InvokeAction(bstrActionName,
varInArgs,
&varOutArgs,
&varReturnVal);
if (SUCCEEDED(hr))
{
SAFEARRAY * psaOutArgs = NULL;
VARIANT varTrackTitle;
psaOutArgs = V_ARRAY(&varOutArgs);
VariantInit(&varTrackTitle);
rgIndices[0] = 0;
hr = SafeArrayGetElement(psaOutArgs,
rgIndices,
(void *)&varTrackTitle);
if (SUCCEEDED(hr))
{
wcout << L"Action invoked successfully\n"
<< L"\tTrack Length == "
<< V_I4(&varReturnVal) << L"\n"
<< L"\tTrack Title == "
<< V_BSTR(&varTrackTitle) << L"\n";
}
else
{
wcerr << L"Failed to get array element -"
<< L" HRESULT 0x"
<< setbase(16)
<< hr << L"\n";
}
VariantClear(&varTrackTitle);
VariantClear(&varReturnVal);
VariantClear(&varOutArgs);
}
else
{
wcerr << L"Failed to invoke action - HRESULT 0x"
<< setbase(16)
<< hr << L"\n";
}
}
else
{
wcerr << L"Failed to insert argument into array - "
<< L"HRESULT 0x"
<< setbase(16)
<< hr << L"\n";
}
SafeArrayDestroy(psa);
}
else
{
wcerr << L"Failed to create safe array\n";
}
SysFreeString(bstrActionName);
}
else
{
wcerr << L"Failed to allocate action name string\n";
}
}