アクションの呼び出し
IUPnPService::InvokeAction メソッドを使用すると、Service オブジェクトに対してアクションを呼び出すことができます。 このメソッドには、アクションの名前と、そのアクションに対する入力引数の配列という 2 つの入力パラメーターがあります。 メソッドには、次の 2 つのパラメーターがあります。
- パラメーター 1 — 入力/出力パラメーター: そのアクションの出力引数の配列。
- パラメーター 2 : 出力パラメーター: 戻り値。
メソッドを使用すると、デバイスでアクションが呼び出されます。 アクションによってデバイスの状態変数が変更された場合、デバイスはイベント通知を生成します。
VBScript の例
次の VBScript コード例では、Service オブジェクトに対して 2 つのアクションを呼び出します。 最初のアクション GetTrackInfo は、1 つの入力引数 (トラック番号) を受け取ります。 GetTrackInfo アクションは、トラックの長さを戻り値として返します。 アクションには 1 つの出力引数もあります。この引数には、メソッドが成功を返した場合にトラック タイトルが含まれます。
GetTrackInfo アクションを呼び出した後、この例では Play アクションを呼び出します。これは引数を受け取らなくなります。 ただし、 InvokeAction の構文には入力引数と出力引数の両方の配列が必要であるため、この例では空の配列 emptyArgs を要素なしで作成する必要があります。 この例では、入力引数と出力引数の両方の InvokeAction に、アクションの名前と共にこの配列を渡します。
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
C++ の例
次の例では、引数なしでアクションを呼び出す C++ 関数を定義します。 InvokeAction には引数の SAFEARRAY を渡す必要があるため、この例では空の SAFEARRAY を作成します。 このアクションは値を返さないか、出力引数を持っていないので、この例では InvokeAction に渡された最後の 2 つの VARIANT 値を無視します。
アクションによってデバイスの状態変数が変更された場合、デバイスはイベント通知を生成します。
#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";
}
}
次の例では、架空の GetTrackInfo アクションを呼び出します。 トラック番号を引数として受け取り、トラックの長さを戻り値として返し、出力引数でトラック タイトルを返します。 このコードは前の例に似ていますが、入力引数の空の SAFEARRAY を 作成する代わりに、トラック番号を含む VARIANT を 挿入します。 InvokeAction が成功を返した場合、この例では戻り値と出力引数の配列を調べます。
#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";
}
}