Decremented Blog

プログラミング、釣り、工作など、ジャンルを特に定めず、適当に書かれたブログです。

IUPnPService::InvokeAction() のコール方法

2007-12-28 23:58:46 | プログラミング・開発
UPnPをAPI経由で使うためには、IUPnPService::InvokeAction()を使う必要がありますが、これがちょっと分かりにくいので、メモを残します。

プロトタイプは、↓見たいな感じなのですが、注意すべきはvarInActionArgsです。
InvokeAction(
BSTR bstrActionName,
VARIANT varInActionArgs,
VARIANT* pvarOutActionArgs,
VARIANT* pvarRetVal);

これには、アクションの引数を配列として入れるのですが、何も引数が無い場合でも、空の配列を渡す必要があります。
具体的には、以下みたいなコードになります。

// 配列を用意
CComSafeArray<VARIANT> argArray;
argArray.Create();

// 引数を用意
CComVariant arg(argArray);

// 戻値を用意
CComVariant argRet, retVal;

// コール
hr = pService->InvokeAction(_bstr_t("GetExternalIPAddress"), arg, &argRet, &retVal);
if(!SUCCEEDED(hr))
return(-1);

C++からCOMって面倒だなあ、そろそろC#にでもするか・・・

COMオブジェクトのアクセスでハマる

2007-12-28 15:07:44 | プログラミング・開発
UPnP APIを操作しようとプログラムを書いていて、単純な間違いで2時間くらいハマりました・・・

IUPnPDeviceFinder::FindByType を使うと、デバイスリストとして IUPnPDevices インターフェースが取得できます。
IUPnPDevices の中身を取得するためには、IUPnPDevices::__NewEnumを使い、 IEnumVARIANT か IEnumUnknown を取得して使います。

私は

IEnumUnknown *pEnumUnknown = NULL;
pUPnPDevices->get__NewEnum((LPUNKNOWN *)&pEnumUnknown);
pEnumUnknown->Next(1, &pDevice, &recv);

と言うコードを書いたのですが、最後のNext()が正常に動作しません。
よく考えたら当たり前で、_NewEnum は、IEnumUnknown では無く IUnknown を返すのだから、次のようにコーディングする必要がありました。

IUnknown *pUnknown=NULL;
pUPnPDevices->get__NewEnum((LPUNKNOWN *)&pUnknown);
IEnumUnknown *pEnumUnknown=NULL;
pUnknown->QueryInterface(IID_IEnumUnknown, (void **)&pEnumUnknown);
pEnumUnknown->Next(1, &pDevice, &recv);

このように、IUnknown から QueryInterface して、IEnumUnknown を取得する必要があります。
よく考えれば、当たり前なんですが・・・

アスキーアートを彫刻してみた - やり方

2007-12-28 10:42:49 | 趣味・その他
私がやった、アスキーアート彫刻を簡単に紹介します。

■準備するもの
・ガラスのコップ(透明で薄めのもの)
・電動ルータ
・ダイヤモンドビット
・透明なシール紙
・プリンタ、パソコン

ルータは、ダイヤモンドビットがセットで、ネットで千円くらいから売っています。
電動アートリューターセット
ネーム入ガラス用電動ルーター
※アフィリエイトです。嫌いな人は楽天トップから検索してください。

■やりかた
1.アスキーアートを適当なペイントツールで書きます
2.左右反転します
3.透明なシール紙に印刷します


4.コップの内側に貼ります


6.印刷に沿って削ります
7.ある程度削ったら、シールをはがして確認します

(手とか、色のある物を中に入れるとわかりやすいです)

8.おかしいところを修正して完成



本当に簡単にできるので、お勧めです。

HTTP/HTTPS over P2P

2007-12-28 10:18:26 | プログラミング・開発
誰でも自分用のWebサーバを簡単に立てられる方法を考えています。
問題は、やはりグローバルIPとルータ越えですね。

以前から、HTTP/HTTPSのリバースプロクシ(SoftEather見たいな物)を使えば、グローバルIPが無くてもWebサーバが立てられると考えています。ルータ越えも簡単ですし。
昔、大学のサーバに自作リバースプロクシを入れて、自宅と友人宅にサーバを立てていました。
一人や二人なら、専用サーバを用意すればいいのですが、多人数となると回線幅の問題から難しそうです。

そこで、Skypeのように、P2P技術を使って上手く出来ないか考えています。
技術的には難しくないのですが、悪用されないための仕組みが難しそうです。
自分専用サーバ限定にして、使用時に毎回認証が必要なようにすれば大丈夫かな?
HTTPSも、Server Name Indicationのおかげで、何とかなりそうだし。

まあ、今の日本なら、多くの家にグローバルIPがあるはずなので、ルータさえ越えられればサーバが立てられそうですが・・・
UPnPも普及してきたので、UPnPを使えばある程度は何とかなるかもしれません。