忍者ブログ
[106]  [105]  [104]  [103]  [102]  [101]  [100]  [99]  [98
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

しばらくopenFrameworksが出てきそうにないけど、wiimote.cppをちょっとだけ読んでみよう。
というのも、業務のほうで確実に必要になってくると思われるので、VC++(Windowsアプリ)からHIDデバイスの情報に、どのようにしてアクセスするのかを知っておきたい。

個人的な備忘録なので、読んでも面白くないぞ。


wiimoteクラスのコンストラクタにはまず、
HidDLL = LoadLibrary(_T("hid.dll"));
とある。HidDLLはHMODULEという型で、どうやらHIDライブラリのインスタンスを差している。そして、
_HidD_SetOutputReport = (hidwrite_ptr) GetProcAddress(HidDLL, "HidD_SetOutputReport");
と続く。_HidD_SetOutputReportは関数ポインタ型で、関数名からDLLに含まれる関数を取得しているらしい。「っつったって、DLLの中の関数名なんか知らねーよ」となるんだけど、それらを書いて(宣言して)あるのがhidsdi.h、ということか。

じゃあGetProcAddressで取得したHidD_SetOutputReportというのはどういう関数なのか。これはHIDからの出力レポートをコピーするアドレスを渡しているらしい。そもHIDって何なの、っていうところもよく分かってないんだけど、要はUSB接続だろうがBluetooth接続だろうが、キーボードとかジョイパッドとかの機器側がHIDを自称していればそれはHIDになるらしい。で、hid.dllの裏側で何が起こってようが、おんなじAPIからHID形式のレポート(機器の情報)が取得できるってことだねー。たぶん。

HIDデバイスからの出力が受け取れることは分かったけど、じゃあどのHIDデバイスがWiiRemoteなのか、指定してやらないといけん。つまり、レポートをどこからコピーすればいいのか?ってこと?
wiimote::Connect関数内の処理なのだけど、なかなか難しいなあ。

まず接続されているHIDデバイスを取得しなきゃいかん。
HidD_GetHidGuid関数(hidsdi.h)でHIDクラス(オブジェクト指向でいうところのクラスではない事はわかるぞ)のGUID(一意な識別子だってさ)を取得する。取得したGUIDをSetupDiGetClassDevs関数(SETUPAPI.H)に渡すと、HIDクラスのデバイスだけが取得される。(HID以外にも色んなクラスのデバイスがあるよ、ってことなんでしょう。)
で、HIDデバイスのリストが得られたので今度は順に見ていくようです。それがSetupDiEnumDeviceInterfaces関数(SETUPAPI.H)で、ようやく個々のHIDデバイスをチェックできる。

さて、どのHIDデバイスがWiiRemoteなのかは、SP_DEVICE_INTERFACE_DATA(HIDデバイスのリスト)を見ていく事になる。
まずSetupDiGetDeviceInterfaceDetail関数(SETUPAPI.H) でデバイスインタフェースの詳細情報を取得するようですが、この関数は2度呼び出されます。1度目は詳細情報のサイズを取得するため、2度目は取得したサイズを元に確保したメモリに詳細情報をコピーするため。うーん、これぞC言語…。
取得されたSP_DEVICE_INTERFACE_DETAIL_DATA構造体はDevicePathなる文字列を持っている。なんでもPCにつながったデバイスはツリー構造の名前空間をなしていて、それがデバイスパスなのだとか。デバイスマネージャを見ると、確かにどのデバイスにもそんなのがある。
このデバイスパスから、CreateFile関数でハンドルを取得する。このハンドルがどうやら、抽象化された個々のHIDデバイスそのものへの参照らしい。やっと。
HidD_GetAttributes関数(hidsdi.h)で機器を識別するためのHIDD_ATTRIBUTES構造体を取得する。これでようやくHIDデバイスのVenderID(任天堂は0x057e)とProductID(WiiRemoteは0x0306)を知ることが出来る。
リストを順に見ていく中でめでたくWiiRemoteを見つけたら、一旦開いたハンドルを閉じて、アクセスレベル(最初は問い合わせのみ、今回は読み書きの許可を求める)を変更して再度CreateFile関数でハンドルを取得する。問題なくハンドルが再度取得できたら、ようやくHIDデバイスとしてWiiRemoteを操作できる。のかな?

で、WiiRemoteからの出力レポート取得は別スレッド上でえんえん実行される。
出力の取得は先程関数ポインタを取得した_HidD_SetOutputReportから。dllの関数をわざわざメンバ変数に代入したのは、別スレッドから呼び出すためなのかな?WinAPIのスレッドはいずれ勉強するとして、とりあえずまあ、いいや。
デバイスへの入力には同じく_HidD_SetOutputReportから行うパターン(非同期)?と、CreateFile関数で取得したハンドルを使ってWriteFile関数でデバイスに書き込むパターン(同期?)が用意されているみたい。これは、接続時に引数で決める。

うーむ、まだまだ分からない事だらけだ。
PR
この記事にコメントする
お名前
タイトル
文字色
メールアドレス
URL
コメント
パスワード   Vodafone絵文字 i-mode絵文字 Ezweb絵文字
この記事へのトラックバック
この記事にトラックバックする:
26歳のハローワールド
カレンダー
03 2024/04 05
S M T W T F S
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
最新コメント
[11/27 gyzwviyehl]
[11/18 Tepexaxyonelo]
[09/12 gomFolley]
[08/16 CypeBachCoece]
[06/02 gb]
[03/06 kishima]
[01/18 KNDY]
[01/16 kage]
[12/23 KNDY]
[12/23 kage]
最新トラックバック
ブログ内検索
アクセス解析
プロフィール
HN:
knd
HP:
自己紹介:
絶賛迷走中。
UNIQLO CALENDAR
忍者ブログ [PR]