작업 호출
IUPnPService::InvokeAction 메서드를 사용하면 Service 개체에서 작업을 호출할 수 있습니다. 이 메서드에는 작업의 이름과 해당 작업에 대한 입력 인수 배열이라는 두 개의 입력 매개 변수가 있습니다. 메서드에는 두 개의 매개 변수가 있습니다.
- 매개 변수 1 - 입력/출력 매개 변수: 해당 작업에 대한 출력 인수 배열입니다.
- 매개 변수 2 - 출력 매개 변수: 반환 값입니다.
메서드를 사용하면 디바이스에서 작업이 호출됩니다. 작업으로 인해 디바이스의 상태 변수가 변경되는 경우 디바이스에서 이벤트 알림을 생성합니다.
VBScript 예제
다음 VBScript 코드 예제에서는 Service 개체에 대해 두 가지 작업을 호출합니다. 첫 번째 작업인 GetTrackInfo는 하나의 입력 인수인 트랙 번호를 사용합니다. GetTrackInfo 작업은 트랙 길이를 반환 값으로 반환합니다. 작업에는 메서드가 성공을 반환하는 경우 트랙 제목을 포함하는 하나의 출력 인수도 있습니다.
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에 전달된 마지막 두 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";
}
}