2010年10月10日日曜日

ハードウェアをアクセスするサンプルコード3.1

main()
int main (void)
{
  変数宣言
  err = IOMasterPort(..., ...);
  エラー処理
  matchingDictionary = IOServiceMatching(...);
  エラー処理
  err = IOServiceGetMatchingServices(..., ..., ...);
  matchingDictionary = 0;
  if ((usbDeviceRef = IOIteratorNext(...)))
  {
    err = dealWithDevice(usbDeviceRef);
    エラー処理
  } else {
    エラー処理
  }
  使用したオブジェクトの解放
}

ここではIOMasterPortでポートを開き、ポートにアクセスするためのオブジェクトとして先ほどのmasterPortを利用します。確実にメモリ領域を取得するために、この命令を最初に入れます。


次に、以下の一文でIO RegistryデータベースにUSBに関して問い合わせるためのオブジェクトを作ります。

matchingDictionary = IOServiceMatching(kIOUSBDeviceClassName);

AppleではこのオブジェクトをDictionaryと読んでいますが、問い合わせたい内容をこのDictionaryに追加して目的の装置やソフトウェアを見つけ出します。

問い合わせの内容を追加する作業は意外と面倒です。USBを例にすると、USBには装置を特定するために企業名を指すVender IDと装置を指すProduct IDがあります。それぞれのIDをCFNumberCreate()と言う関数でCore Foundationのオブジェクトに変換し、CFDictionaryAddValue()でDictionaryオブジェクトに追加し、不要になったCore FoundationのオブジェクトをCFRelease()で解放し、0を代入してカーネルが必要に応じてパージしても良いようにします。

このサンプルコードでは、USB全体をターゲットにしますので、最初の IOServiceMatching()だけでDictionaryオブジェクトの作成が終わり、すぐにIOServiceGetMatchingServices()を読んでUSBに関連するデータを取得します。

IOServiceGetMatchingServices()では三つ目の引数として&iteratorというオブジェクトに入れています。USBやPCI拡張カードでは同じ装置が何台も接続されているかもしれません。&iteratorオブジェクトは複数の装置がつながっている場合を想定したオブジェクトで、装置に関するデータをif文で一つずつ取り出して処理します。この処理をするのがここで書かれている二つ目の関数であるdealWithDevice()です。

topに戻る

0 件のコメント: