Palm Programmer's Laboratory
Palm OS Programmer's Companion Volume II/1-4
1-4 データの送信
このセクションでは、Exchange Managerを使ってどのようにデータを送信するか、について説明します。以下のトピックについて解説します。
- 単独オブジェクトの送信
- 複数オブジェクトの送信
- 送信コマンドの実装
単独オブジェクトの送信
Exchange Managerの最も一般的な使い方は、単独オブジェクトの送受信です。オブジェクトを送信するには、以下のようにします。
- ExgSocketType構造体を生成し、どのライブラリを使用するか及び送信するデータについての説明を含めて初期化する。詳しくはExchange Socket 構造体の初期化?を参照して下さい。
- Exchange ライブラリとの接続を確立するために、ExgPut をコールします。
- データを送信する回数だけ、ExgSend をコールします。この関数では、送信するバイト数を特定します。そしてExgSend は送信したバイト数を返します。コール後にまだ送信すべきデータが残っているなら、その分コールします。
- 接続を終了するために、ExgDisconnect をコールします。戻り値がゼロのときは、送信が成功したということです。しかし、受信側がデータを保持できたことを必ずしも意味しません。オブジェクトを受け取る対象のアプリケーションが受信側デバイスに存在しないなら、データは破棄されてしまいます。また、ユーザが受信データを破棄することもあります。
ExgSend 関数は、それが帰ってくるまでプログラムの実行をブロックすることに注意して下さい。しかし、ライブラリが提供するダイアログの多くは、送信が進行中であることを示し続け、操作をキャンセルすることを許可します。
エラーが起きたときは、Exchange Manager は自動的にエラーダイアログを表示します。Exchange Manager ルーチンからエラーコードを確認することは必要ですが、エラーダイアログを表示する必要はありません。Exchange Manager が代わりにやってくれます。
例として、現在描画しているウィンドウをPalm ハンドヘルドから別のPalm ハンドヘルドに送る方法をListing 1.3 に示します。それは Palm OS SDKに含まれる赤外線通信アプリケーションのコードを修正したものです。
Listing 1.3 Exchange Manager を使用したデータ送信
Err SendData(void) { ExgSocketType exgSocket; UInt32 size = 0; UInt32 sizeSent = 0; Err err = 0; BitmapType *bmpP; // copy draw area into the bitmap SaveWindow(); bmpP = PrvGetBitmap(canvasWinH, &size, &err); // Is there data in the field? if (!err && size) { // important to init structure to zeros... MemSet(&exgSocket,sizeof(exgSocket),0); exgSocket.description = "Beamer picture"; exgSocket.name = "Beamer.pbm"; exgSocket.length = size; err = ExgPut(&exgSocket); if (!err) { sizeSent = ExgSend(&exgSocket,bmpP,size,&err); ExgDisconnect(&exgSocket,err); } } if (bmpP) MemPtrFree(bmpP); return err; }
複数オブジェクトの送信
Palm OS 4.0 以降では、Exchange Library がサポートするのであれば、単一の接続で複数のオブジェクトを送信することができます。複数オブジェクトを送信するには、以下のようにします。
- ExgSocketType構造体を生成し、どのライブラリを使用するか及び送信するデータについての説明を含めて初期化する。詳しくはExchange Socket 構造体の初期化?を参照して下さい。また、count フィールドの値に送信するオブジェクトの数をセットします。
- Exchange ライブラリとの接続を確立するために、ExgConnect をコールします。
- 送信するオブジェクトごとに、以下のようにします。
- 新しいオブジェクトの開始を知らせるために、ExgPut をコールします。
- データ送信の回数だけ ExgSend をコールします。この関数では、送信するバイト数を指定します。ExgSend は実際に送信されたバイト数を返します。コール後にまだ送信すべきデータが残っているなら、複数回のコールが必要です。
- 接続を終了するために、ExgDisconnect をコールします。戻り値がゼロのときは、送信が成功したということです。しかし、受信側がデータを保持できたことを必ずしも意味しません。オブジェクトを受け取る対象のアプリケーションが受信側デバイスに存在しないなら、データは破棄されてしまいます。また、ユーザが受信データを破棄することもあります。
ExgConnect のコールは必須ではありません。赤外線ライブラリなどの一部の Exchange ライブラリは複数オブジェクトの送信をサポートしていますが、ExgConnectをサポートしていません。もし ExgConnect がエラーを返したなら、最初の ExgPut コールで接続が開始されます。最初の ExgPut コールが成功したなら、あとは続けてオブジェクトを送信するだけです。 ExgConnect をサポートするライブラリは ExgConnect を使わなくても複数オブジェクトの送信をサポートする、ということを Listing 1.4 に示します。
Listing 1.4 複数オブジェクトの送信
Boolean isConnected = false; err = ExgConnect(&exgSocket); //optional if (!err) isConnected = true; if (!err || err == exgErrNotSupported) { while (/* we have objects to send */) { err = ExgPut(&exgSocket); if (!isConnected && !err) isConnected = true; //auto-connected on first put. while (!err && (sizeSent < size)) sizeSent += ExgSend(&exgSocket,dataP,size,&err); if (err) break; } } if (isConnected) ExgDisconnect(&exgSocket, err);
送信コマンドの実装
Palm OS 4.0 では、ビルトインアプリケーションのメニューには送信(Send)コマンドがあります。このコマンドの目的は、利用可能なあらゆる転送メカニズムを用いてデータ送信を行なえるようにすることです。
Exchange Manager は、_send URL スキームを定義します。その意図は、送信をサポートするどの Exchange ライブラリでも_send スキームに登録されることです。現時点では、リリースROMでは SMS ライブラリだけがこのスキームに登録されています。Bluetooth サポートが利用可能になったら、Bluetooth ライブラリがこのスキームに登録されるでしょう。赤外線ライブラリは_send スキームに登録されていません。
あなたのアプリケーションで送信コマンドを実装するには、プレフィックスとして exgSendPrefix をつけた URL を作り、通常の作法でデータを送信します。送信やビーム通信に対して登録された Exchange ライブラリ(赤外線ライブラリを含む)からの選択を可能にするために、exgSendBeamPrefix を代わりに使うこともできます。あるスキームに対して複数の Exchange ライブラリが登録されているときに Exchange Manager がダイアログを表示できるように、前述のプレフィックスはどちらもクエスチョンマーク( ? )で始まります。
現在の Palm OS 4.0 リリースROMでは、SMS Exchange ライブラリだけが _send スキームをサポートしています。よって、exgSendPrefix を使ってもダイアログは表示されません。ユーザが後から Bluetooth サポートを追加したら、ダイアログは表示されます。
注意:デバッグROMでは、ローカル Exchange ライブラリは利用可能な転送メカニズムの一つに挙げられます。このことにより、送信コマンドをデバッグすることができます。ローカル Exchange ライブラリはリリースROMでの送信時にはダイアログに表示されません。
どのように送信コマンドを実装するかの例は、Palm OS SDK に含まれるメモ帳アプリケーションのサンプルコードを参照して下さい。