INtimeドキュメンタリトップへ

NT側グラフ表示アプリケーション

10月28日・・・NTXアプリケーション作成

INtime®側アプリケーション/NT側アプリケーション間、あるいはINtime®アプリケーション/ INtime®アプリケーション間でメールボックスを通じて通信を行う場合、どちらか一方に属するメールボックスのハンドルを取得する必要があります。


INtime®・NTX間通信の手法
メールボックスのオブジェクトハンドルの取得方法
 CatalogRtHandleとLookupRtHandle
  ・ メールボックスを含むアプリケーションはインターフェース用のメールボックスのハン
     ドル値をある名前でカタログする必要があります。カタログする位置は、ルートディレクトリや、
     そのルートディレクトリに属するプロセスのディレクトリなど、任意に指定できます。
  ・ メールボックスを検索する側のアプリケーションはメールボックスオブジェクトがカタログされ
     ているディレクトリと、カタログ名前を知っておく必要があります。 
CatalogRtHandle()
BOOL CatalogRtHandle(
  RTHANDLE hProcess, // RTプロセスのハンドル
  RTHANDLE hObject, // カタログするオブジェクトのハンドル
  LPSTR lpszName                      // カタログ名
);

LookupRtHandle()
RTHANDLE LookupRtHandle(
  RTHANDLE hProcess, // RTプロセスハンドル                      
  LPSTR lpszName, // オブジェクトのカタログ名
  DWORD dwMilliseconds // 検索するためのタイムアウト値
);
Windows側(NTXアプリケーション)ではntxCatalogRtHandle()とntxLookupRtHandle()となります。

アナログデータ変換値取得スレッドを含むRTプロセスに含まれるメールボックスを検索する。
                   
メールボックスオブジェクトハンドルの取得

 メールボックスオブジェクトハンドルを取得する為にはまずルートRtプロセスハンドルの取得 (ntxGetRootRtProcess) ↓
RT側のプロセスオブジェクトの取得(ntxLookupNtxHandle)

使用するメールボックスオブジェクトハンドルの取得(nyxLookupNtxHandle)
コード上

//ルートプロセスハンドラを取得する

if( (m_RootProcess = ntxGetRootRtProcess(NTX_LOCAL)) == NTX_BAD_NTXHANDLE )
{ AfxMessageBox(
"ルートプロセスハンドル取得エラー" ,MB_ICONERROR | MB_OKCANCEL,0); exit(0); } //ルートプロセス下にあるINtime®側のプロセスを検索しハンドラを取得する if ( (m_InTimeDocProcess = ntxLookupNtxhandle(m_RootProcess,rt_process, 0xffff)) == NTX_BAD_NTXHANDLE) { AfxMessageBox("INtimeDocプロセスハンドル取得エラー" , MB_ICONERROR | MB_OKCANCEL,0); exit(0); } //取得したINtime®側のハンドラを使用してデータの受け渡しで使用するメールボックスを検索 //ハンドルを取得する。 If((m_RtGraphMailbox=ntxLookupNtxhandle(m_InTimeDocProcess,rt_nt_mbx, 0xffff)) == NTX_BAD_NTXHANDLE) { AfxMessageBox("メールボックスハンドル取得エラー" , MB_ICONERROR | MB_OKCANCEL,0); exit(0); }
通信タイミング
INtime®側で送信されたメールボックスを受信するタイミングはサンプルにあったタイマ(OnTimer())を使えばいいのだと思い、タイマを使用して受信するタイミングを作成しました。しかし、これではRT側と同期を取らずに,NT側の独自ポーリング周期(タイマ周期)でメールボックスを検索するような処理になってしまうため、スレッドを生成し、そのスレッドの先頭でメールボックスにオブジェクトを受信する処理に変更しました。
このスレッド作成に苦労しました。
NT側でのスレッドをどのように作成したら良いのか解らなかった為、VCのヘルプにて"スレッド"で検索して調べました。
出てきた関数は、_beginthread関数が出てきました。この関数を使用して作成する事にしました。この関数の第1引数(新しいスレッドの実行開始アドレス)の設定が上手く出来ない為、諦めCreateThread関数を使用する事に。
この関数を使用しても同じエラーでどうにもダメでした。
次にCWinThreadクラスを使用してみました。CWinThredクラスの派生クラスをまず作成しました。
使い方(関数の使用方法)などどうすれば解らなかった為、今度はインターネットで調べてみる事にしました。そこにちょっと参考に出来そうな簡単なものを見つけました。作成した、スレッドを起動する為には
afxBeginThread関数をコールすれば良いようでした。
afxBeginThread関数がコールされる事によりCWinThreadオブジェクトを新規に作成しCreateThreadを呼び出すようになっているようです。

実際、グラフの描画を行なっているクラスと今回のスレッド内でデータを取得すると言う事で、取得したデータのやり取りをどうするのかが問題になりました。
スレッド内にダイアログ側のデータを渡す方法が全くわからない状態でした。
クラスのメンバ変数として扱う事でデータのやり取りを行うように修正しましたが、とメモリ破壊を起こす状況でした。
これには困りました。このやり取りが出来ないとグラフの表示が出来ない為です。
最終的に、原因がわかりました。私が、スレッドクラスポインタとして扱っていた値が全く違うものだったためです。
AfxbeginThread()コールで取得した値が、スレッドクラスのポインタで、その値を使用してスレッドクラスのメンバ変数等にアクセスしなければいけないものを、RUNTIME_CLASS(XXXX←クラス名)での値でアクセスしようとしていました。
これを直すことにより、スレッドクラスのメンバ変数などにアクセスできるようになり、取り込んだデータをダイアログ関数で使用することができ、グラフの描画が行なえるようになりました。


※TenAsys®, INtime®, eVM® and iRMX® are registered trademarks in USA of the TenAsys Corporation.