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

Tomoya Sakaguchi sakaguchi @ sec.co.jp
2007年 11月 20日 (火) 17:05:20 JST


株式会社セックの坂口です。


Windows上での、データポートとサービスポートを持つ
コンポーネント作成の件についてですが、自己解決しました。

最初に投稿した質問メールに書かれている内容を実行することで、
データポートとサービスポートを持ち、かつ、サービスポート
利用時に強制終了しないコンポーネントを作成できました。

お手数お掛け致しました。

失礼します。


Ando Noriaki さんは書きました:
> セック 坂口様
> 
> 産総研 安藤です
> 
> お世話になっております。
> 表記の件につきましては、現在調査中ですのでしばらくお待ちください。
> ただ、Windows版に関してはどちらかというと
> セックさんの方が詳しいのではないでしょうか(笑
> 
> 
> 07/11/19 に Tomoya Sakaguchi<sakaguchi @ sec.co.jp> さんは書きました:
>> 株式会社セックの坂口と申します。
>>
>>
>> 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 メーリングリストの案内