IUPnPService
COMIDispatch (デュアル)comobj 経由でメソッド名による遅延バインド呼び出しができます(vtableインデックス不要)。公式ドキュメント
IUPnPService インターフェイスを使用すると、アプリケーションはサービスのインスタンスに対して状態変数を照会し、アクションを呼び出すことができます。
メソッド 6
vtbl = vtable インデックス(0始まり)。IDispatch 実装のため HSP ではメソッド名でも呼べます(上記)。低レベルの index 呼び出し用に vtbl も掲載。0〜2 は IUnknown。
QueryStateVariable メソッドは、指定されたサービスの状態変数の値を返します。
| bstrVariableName | LPWSTR | in | 値を返す対象の状態変数を指定します。 |
| pValue | VARIANT* | out | bstrVariableName で指定された変数の値への参照を受け取ります。返されるデータの型は、クエリを実行した状態変数によって異なります。 このパラメーターを解放するには、VariantClear を使用します。 |
戻り値
メソッドが成功した場合、戻り値は S_OK です。それ以外の場合、メソッドは WinError.h で定義されている COM エラーコード、または次の表に示す UPnP 固有の戻り値のいずれかを返します。これらの値の一部は、UPnP 認定デバイスからエラーを受信したことを示します。詳細については、Device Error Codes を参照してください。
| 戻り値 | 説明 |
|---|---|
| 変数はイベント通知の対象ではなく、リモートクエリがエラーコードを返しました。これはトランスポートエラーではありません。デバイスは要求を受信しましたが、エラーを返しました。 | |
| デバイスが 30 秒のタイムアウト時間内に応答しませんでした。 | |
| 変数が存在しません。 | |
| UPnP プロトコルレベルでの問題により、クエリが完了しませんでした。 | |
| 変数はイベント通知の対象ではなく、HTTP の問題により値のリモートクエリが失敗しました。HTTP エラーコードを取得するには、 IUPnPService::LastTransportStatus を使用します。 | |
| 変数はイベント通知の対象ですが、UPnP ソフトウェアはイベント通知をまだ待機しているため、値を返すことができません。 |
解説(Remarks)
UPnP フォーラムは、このメソッドの使用を推奨していません。可能であれば、サービス固有のアクションが用意されている場合はそちらを使用してください。
このメソッドは、イベント通知の対象となる変数の値をサービスオブジェクトのローカルキャッシュから取得します。キャッシュには、最後のイベント通知で示された各変数の値が格納されています。イベント通知の対象ではない変数の値は、デバイスにリモートクエリを送信して取得します。
サービスが最初に初期化されてから最初のイベントを処理するまでの間に、アプリケーションがイベント通知対象の状態変数に対してこのメソッドを呼び出した場合、UPNP_E_VARIABLE_VALUE_UNKNOWN が返されます。
イベントを使用しないサービスに対してアプリケーションがこのメソッドを呼び出し、HTTP 要求が失敗した場合、UPNP_E_TRANSPORT_ERROR が返されます。状態を確認するには、 IUPnPService::LastTransportStatus を使用します。
この問題を回避するには、コントロールポイントで time.tz ではなく dataTime.tz 変数型を使用してください。
デバイス上のメソッドを呼び出します。
| bstrActionName | LPWSTR | in | 呼び出すメソッドを指定します。 |
| vInActionArgs | VARIANT | in | メソッドへの入力引数の配列を指定します。アクションに入力引数がない場合、このパラメーターには空の配列を指定する必要があります。 この配列の内容はサービスごとに異なります。 |
| pvOutActionArgs | VARIANT* | inout | 入力時には空の配列への参照を格納します。出力時には出力引数の配列への参照を受け取ります。アクションに出力引数がない場合、このパラメーターには空の配列が格納されます。 このパラメーターの内容はサービスごとに異なります。 このパラメーターは VariantClear で解放してください。 |
| pvRetVal | VARIANT* | out | 入力時には空の配列への参照を格納します。出力時には、このアクションの戻り値を格納する VARIANT への参照を受け取ります。 アクションの呼び出し後にデバイスがエラーを返し、このパラメーターが NULL に設定されていない場合、戻り時にこのパラメーターにはエラーを説明する固有のテキストが格納されます。デバイスが返すエラーの詳細については、Device Error Codes のドキュメントを参照してください。 このパラメーターは VariantClear で解放してください。 |
戻り値
メソッドが成功した場合、戻り値は S_OK です。それ以外の場合、メソッドは WinError.h で定義されている COM エラーコード、または次の表に示す UPnP 固有の戻り値のいずれかを返します。これらの値の一部は、UPnP 認定デバイスからエラーを受信したことを示します。詳細については、Device Error Codes を参照してください。
| 戻り値 | 説明 |
|---|---|
| デバイスで内部エラーが発生しました。要求を実行できませんでした。 | |
| 不明なエラーが発生しました。 | |
| デバイスが 30 秒のタイムアウト時間内に応答しませんでした。 | |
| デバイスが処理できない応答を送信しました。たとえば、応答が破損していた場合などです。 | |
| そのアクションはデバイスでサポートされていません。 | |
| vInActionArgs で渡された引数のうち、1 つ以上が無効です。 | |
| UPnP 制御プロトコルレベルでエラーが発生しました。 | |
|
HTTP エラーが発生しました。実際の HTTP ステータスコードを取得するには、IUPnPService::LastTransportStatus プロパティを使用します。
メモ このエラーコードは、SOAP 応答が 100 キロバイトを超えた場合にも返されます。
|
解説(Remarks)
アプリケーションが InvokeAction メソッドを呼び出す際には、サービスが期待する引数と一致する引数のリストを渡します。コントロールポイントは、これらの VARIANT 引数を必要な型にマップします。使用されるマッピングを次の表に示します。
| データ型 | MSXML が返す型 |
|---|---|
| SDT_STRING = 0 | VT_BSTR |
| SDT_NUMBER | VT_BSTR |
| SDT_INT | VT_I4 |
| SDT_FIXED_14_4 | VT_CY |
| SDT_BOOLEAN | VT_BOOL |
| SDT_DATETIME_ISO8601 | VT_DATE |
| SDT_DATETIME_ISO8601TZ | VT_DATE |
| SDT_DATE_ISO8601 | VT_DATE |
| SDT_TIME_ISO8601 | VT_DATE |
| SDT_TIME_ISO8601TZ | VT_DATE |
| SDT_I1 | VT_I1 |
| SDT_I2 | VT_I2 |
| SDT_I4 | VT_I4 |
| SDT_UI1 | VT_UI1 |
| SDT_UI2 | VT_UI2 |
| SDT_UI4 | VT_UI4 |
| SDT_R4 | VT_FLOAT |
| SDT_R8 | VT_DOUBLE |
| SDT_FLOAT | VT_DOUBLE |
| SDT_UUID | VT_BSTR |
| SDT_BIN_BASE64 | VT_ARRAY |
| SDT_BIN_HEX | VT_ARRAY |
| SDT_CHAR | VT_UI2 (wchar) |
| SDT_URI | VT_BSTR |
この問題を回避するには、非整数の数値に対する UPnP データ型として float ではなく r4 を使用してください。
ServiceTypeIdentifier プロパティは、デバイスのサービス型識別子を指定します。
| pVal | LPWSTR* | out | サービス型識別子を格納する文字列への参照を受け取ります。不要になったら、この文字列を SysFreeString で解放してください。 |
戻り値
C++ の場合: このプロパティの "get" メソッドが成功した場合、戻り値は S_OK です。それ以外の場合、メソッドは WinError.h で定義されている COM エラーコードのいずれかを返します。
AddCallback メソッドは、アプリケーションのコールバックを UPnP フレームワークに登録します。
| pUnkCallback | IUnknown* | in | 登録するコールバックを含むインターフェイスへの参照を指定します。pUnkCallback が参照するオブジェクトは、 IUPnPServiceCallback インターフェイスまたは IDispatch インターフェイスのいずれかをサポートしている必要があります。 |
戻り値
メソッドが成功した場合、戻り値は S_OK です。それ以外の場合、メソッドは WinError.h で定義されている COM エラーコードのいずれかを返します。
解説(Remarks)
このメソッドをコールバック内から呼び出さないでください。メモリ破損が発生します。
複数のコールバックが登録されている場合、UPnP フレームワークはコールバックを順番に呼び出します。
pUnkCallback が参照するオブジェクトは、 IUPnPServiceCallback インターフェイスまたは IDispatch インターフェイスのいずれかをサポートしている必要があります。 AddCallback メソッドは、まず pUnkCallback に対して IUPnPServiceCallback インターフェイスを照会します。このインターフェイスがサポートされていない場合、 AddCallback メソッドは次に pUnkCallback に対して IDispatch インターフェイスを照会します。IDispatch インターフェイスもサポートされていない場合、両方のチェックが失敗し、 AddCallback メソッドは E_FAIL を返します。
IDispatch のみがサポートされている場合、サービスオブジェクトは、ディスパッチ ID にゼロ (既定のメソッドを示します) を指定して IDispatch::Invoke を呼び出すことでコールバックを実行します。この既定の IDispatch メソッドには、 IUPnPServiceCallback メソッドと同じパラメーターが渡されますが、最初のパラメーターにはコールバックが呼び出された理由を示す文字列が渡されます。有効な値は VARIABLE_UPDATE と SERVICE_INSTANCE_DIED です。
このメソッドには次の引数があります。
- コールバックが呼び出された理由。状態変数が変化した (VARIABLE_UPDATE) か、サービスインスタンスが利用できなくなった (SERVICE_INSTANCE_DIED) かのいずれかの理由で呼び出されます。
- コールバックの呼び出し対象となるサービスオブジェクト。
状態変数の変化によりコールバックが呼び出された場合、メソッドにはさらに 2 つの引数が渡されます。
- 変化した変数の名前。
- 新しい値。
Id プロパティは、サービスのサービス ID を指定します。
| pbstrId | LPWSTR* | out | サービス ID への参照を受け取ります。不要になったら、この文字列を SysFreeString で解放してください。 |
戻り値
C++ の場合: このプロパティの "get" メソッドが成功した場合、戻り値は S_OK です。それ以外の場合、メソッドは WinError.h で定義されている COM エラーコードのいずれかを返します。
LastTransportStatus プロパティは、イベント通知対象の変数に関するクエリについて、最後の IUPnPService::InvokeAction 操作の HTTP ステータスを示します。
| plValue | INT* | out | ステータスへの参照を受け取ります。plValue が HTTP ステータス 200 の場合、操作は成功しています。 |
戻り値
C++ の場合: このプロパティの "get" メソッドが成功した場合、戻り値は S_OK です。それ以外の場合、メソッドは WinError.h で定義されている COM エラーコードのいずれかを返します。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
HSP用 COM定義
#usecom / #comfunc によるHSPのCOM呼び出し定義。数字は vtbl インデックス(0始まり)。クラスIDが無い場合 #usecom の末尾は "{}"、ある場合は "{CLSID}"。
#define global IID_IUPnPService "{A295019C-DC65-47DD-90DC-7FE918A1AB44}" #usecom global IUPnPService IID_IUPnPService "{}" #comfunc global IUPnPService_QueryStateVariable 7 wstr,var #comfunc global IUPnPService_InvokeAction 8 wstr,int,var,var #comfunc global IUPnPService_get_ServiceTypeIdentifier 9 var #comfunc global IUPnPService_AddCallback 10 sptr #comfunc global IUPnPService_get_Id 11 var #comfunc global IUPnPService_get_LastTransportStatus 12 var ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数は var(変数直渡し)。varptr 方式にも切替可。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。 ; ※IDispatch 実装。HSP では comobj 経由でメソッド名による呼び出しも可能(vtbl 不要)。#define global IID_IUPnPService "{A295019C-DC65-47DD-90DC-7FE918A1AB44}" #usecom global IUPnPService IID_IUPnPService "{}" #comfunc global IUPnPService_QueryStateVariable 7 wstr,sptr #comfunc global IUPnPService_InvokeAction 8 wstr,int,sptr,sptr #comfunc global IUPnPService_get_ServiceTypeIdentifier 9 sptr #comfunc global IUPnPService_AddCallback 10 sptr #comfunc global IUPnPService_get_Id 11 sptr #comfunc global IUPnPService_get_LastTransportStatus 12 sptr ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。 ; ※IDispatch 実装。HSP では comobj 経由でメソッド名による呼び出しも可能(vtbl 不要)。