[openrtm-users 00274] データポートとサービスポートの共存によるエラー(Win)

Tomoya Sakaguchi sakaguchi @ sec.co.jp
2007年 11月 19日 (月) 16:32:23 JST


株式会社セックの坂口と申します。


Windows上で、InPort(もしくはOutPort)とサービスポートを持つ
コンポーネントを作成する方法がわかりません。ご存知の方が
いれば、教えていただけないでしょうか?

私が上記のコンポーネント作成を試みたとき、以下の問題が発生しました。

(1)サービスポートとデータポートを持つコンポーネントをWindowsで
      ビルドすると、「dllimport スタティック データ メンバ の定義は
      許されません。」というエラーが発生する。

(2)VC++のプロパティの「C/C++のプリプロセッサ」の定義から
      USE_stub_in_nt_dllを削除するとビルドは通るが、コンポーネントの
      起動時に落ちる。

(3)コンポーネントのヘッダファイルに、「#define USE_stub_in_nt_dll」
      の1行を加えてビルドを行うと、コンポーネントの起動時には落ちなく
      なるが、サービスポートによる通信時にエラーが発生する。


詳細は以下に示します。

------------------------------------------------------------
(1)ビルド時に、以下の警告・エラーが出る。
      「dll リンクが一貫していません。」
      「dllimport スタティック データ メンバ の定義は許されません。」

再現手順を以下に示します。

(a)Linuxのrtc-templateを用いてサービスポートのソースコードを
      含むコンポーネントのソースコード作成します。例として、以下の
      ようなスクリプトを用います。

-ここから-

rtc-template -bcxx \
            --module-name=MySample --module-type='DataFlowComponent' \
            --module-desc='Sample' \
            --module-version=1.0 --module-vendor='SEC' \
            --module-category=sample \
            --module-comp-type=COMMUTATIVE --module-act-type=SPORADIC \
            --module-max-inst=10 \
            --inport=SampleIn0:TimedSample \
            --config="Param0:long:2" \
            --consumer=SampleService0:sampleService0:SampleService \
            --consumer-idl=SampleService.idl

-ここまで-

(b)Windowsのrtc-template.py(テンプレート作成スクリプト)を
      用いてVisualC++のプロジェクトファイルを含むソースコードを
      作成します。スクリプトの内容は、Linuxで使用したスクリプトの
      実行ファイル名や行末の円マークを^に修正したものを利用します。

(c)Linuxのrtc-templateで作成したソースコードをWindows版のソース
      コードを上書きし、プロジェクトファイルをオープンします。

      このような手続きを行っているのは、Windowsのrtc-templateでは
      サービスを含むソースコードを生成できないからです。

(d)オープン後、サービスについて記述されているファイル(この場合、
      SampleService.idl)のidlコンパイルを実行を行います。

(e)スケルトン、スタブを作成し、そのスタブファイル(*Stub.cpp/h)を
      プロジェクトに追加します。

(f)ビルドを実行します。

以上のように手順でコンポーネントを作成していくと、「dll リンクが一貫
していません。」という警告メッセージや、「dllimportスタティックデータ
メンバ の定義は許されません。」というエラーが発生します。


------------------------------------------------------------
(2)ビルドは成功するが、dataport.hhファイルのクラスInPortAnyの
      _thisメンバ関数でコンポーネントが落ちる。

再現手順を以下に示します。

(a)(1)の(a)から(e)までを行います。

(b)プロジェクトのプロパティで、C/C++のプリプロセッサの定義にある
      USE_stub_in_nt_dllを削除します。
     
      私が調べた限りでは、サービスポートを利用する場合、C/C++のプリ
      プロセッサの定義にUSE_stub_in_nt_dllを含んでいませんでした。
      したがって、その項目を削除すればいいと考えました。これは、
      OpenRTM-aist-0.4.1ーWinのパッケージに付属しているサンプルコード
      を参考にしました。

(c)ビルドを実行します。

以上のように手順でコンポーネントを作成していくと、今度はビルドは
正常に終了します。しかし、このコンポーネントは実行時に落ちます。

デバッグモードでビルドし、どこで落ちているかを調査しました結果、
dataport.hhというファイルに記述されているInPortAnyクラスの_this
メンバ関数で落ちていることがわかりました。dataport.hhファイルは、
「C:\Program Files\OpenRTM-aist\rtm\idl」にあります。


------------------------------------------------------------
(3)サービスポートの利用時に以下のエラーが発生する。
      「omniORB: ERROR -- the application attempted to invoke
        an operation on a nil refrence.」

再現手順を以下に示します。

(a)(2)の(a)から(b)までを行います。

(b)コンポーネントのヘッダファイルに、「#define USE_stub_in_nt_dll」
      の1行を加えます。

      OpenRTM-aist-0.4.1ーWinのパッケージに付属しているサンプルRTC、
      MyServiceProviderにInPortを持たせるようにソースコードを修正し、
      ビルドを行うと、(2)と同じ結果になりました。
      また、同サンプルRTC、ConsokeInにサービスコンシューマポートを
      持たせるようにソースコードを修正し、ビルドを行った結果、(1)
      と同じビルドエラーメッセージが出現しました。

      これらより、データポート(InPort・OutPort)を持つコンポーネント
      は、C/C++のプリプロセッサの定義にUSE_stub_in_nt_dllを含んで
      いないと実行時にエラーが発生し、また、サービスポートは、C/C++の
      プリプロセッサの定義にUSE_stub_in_nt_dllを含んでいると、ビルド
      が通らないと判断しました。

      上記のように、データポートとサービスポートの共存は、/C++のプリ
      プロセッサの定義、USE_stub_in_nt_dllの排他的な問題によると判断
      しました。この問題を解決するためには、データポートのソースコード
      のビルド時にはUSE_stub_in_nt_dllを定義し、サービスポートに関する
      ビルドではUSE_stub_in_nt_dllを定義しないようにしないとならないと
      考え、コンポーネントのヘッダファイルに
      「#define USE_stub_in_nt_dll」を付加するようにしました。

(c)ビルドを実行します。

以上のように手順でコンポーネントを作成していくと、ビルドは成功
します。そして、この作成されたコンポーネントを実行すると(2)とは
違い、コンポーネント生成時に落ちることはありません。

しかし、このコンポーネントからサービスポートを利用してサービスを要求
したとき、「omniORB: ERROR -- the application attempted to invoke
an operation on a nil refrence.」というエラーが発生します。

サービスコンシューマからサービスプロバイダにサービスが届いていると、
サービスプロバイダの要求されたサービスに関するコードが実行されるはず
ですが、今回はブレークポイントを使って調べてみたところ、実行されて
いませんでした。


--

以上の3点です。
よろしくお願いいたします。



openrtm-users メーリングリストの案内