[openrtm-users 00032] Re: Windowsへの移植
Noriaki Ando
n-ando @ aist.go.jp
2005年 10月 19日 (水) 16:17:57 JST
稲村様
安藤@産総研です
VC6でコンパイルが通った(というより通した)ということで
ありがとうございます。
次期バージョンに以下の変更を反映させたいと思います。
できれば、修正したソースやプロジェクトファイル等提供
をしていただけないでしょうか?
安藤慶昭@独立行政法人産業技術総合研究所 研究員
知能システム研究部門 タスクインテリジェンス研究グループ
〒305-8568 茨城県つくば市梅園1-1-1 中央第2
TEL: 029-861-5981 FAX: 029-861-5971
n-ando @ aist.go.jp, n-ando @ ieee.org
> 稲村@IHIです。
>
> ずいぶん時間が経ってしまいましたが、報告します。
> VC6で使えるようになりました。
>
>
> [1] 全般
> using namespace std;を削除し、std名前空間を明示する。
> これをやらないと、いろいろとコンパイルエラーがでる。
> 以下のファイルを修正。
> RtcBase.h,RtcBase.cpp,
> RtcConfig.h,
> RtcManager.h,RtcManager.cpp,
> RtcModuleProfile.h,RtcModuleProfile.cpp,
> RtcNaming.h,RtcNaming.cpp,
> RtcOutPort.h,
> RtcOutPortBase.h,RtcOutPortBase.cpp,
>
>
>
> [2] RtcBase.h
>
> 1. USLEEPマクロをVC6で動作するように修正。
> #if defined(_MSC_VER) && (_MSC_VER <= 1200)
> # define USLEEP(x) Sleep(x/1000);
> #else
> # define USLEEP(x) usleep(x);
> #endif
>
> 2. ComponentStateをenumで定義。
> VC6ではconstで定義した定数を定数式と判断してくれないためcaseラベルに使えない。 そのため、以下のようにenumで定義しなおした。
> 数値が一致することを常に確認しなければならない。これは、苦肉の策。もっと良いやり方はないか?
> #if defined(_MSC_VER) && (_MSC_VER <= 1200)
> enum ComponentStateVC6{
> RTC_UNKNOWN = 0,
> RTC_BORN = 1,
> RTC_INITIALIZING= 2,
> RTC_READY = 3,
> RTC_STARTING = 4,
> RTC_ACTIVE = 5,
> RTC_STOPPING = 6,
> RTC_ABORTING = 7,
> RTC_ERROR = 8,
> RTC_FATAL_ERROR = 9,
> RTC_EXITING = 10,
> };
> #else
> const ComponentState RTC_UNKNOWN = RTM::RTComponent::RTC_UNKNOWN;
> const ComponentState RTC_BORN = RTM::RTComponent::RTC_BORN;
> const ComponentState RTC_INITIALIZING = RTM::RTComponent::RTC_INITIALIZING;
> const ComponentState RTC_READY = RTM::RTComponent::RTC_READY;
> const ComponentState RTC_STARTING = RTM::RTComponent::RTC_STARTING;
> const ComponentState RTC_ACTIVE = RTM::RTComponent::RTC_ACTIVE;
> const ComponentState RTC_STOPPING = RTM::RTComponent::RTC_STOPPING;
> const ComponentState RTC_ABORTING = RTM::RTComponent::RTC_ABORTING;
> const ComponentState RTC_ERROR = RTM::RTComponent::RTC_ERROR;
> const ComponentState RTC_FATAL_ERROR = RTM::RTComponent::RTC_FATAL_ERROR;
> const ComponentState RTC_EXITING = RTM::RTComponent::RTC_EXITING;
> #endif
>
> 3. friend class ThreadStates; 追加
> class ThreadStatesのコンストラクタで使用しているRUNNINGは、
> RtcBaseクラスのprotectedのため、エラーとなる。
> TreadStatesをRtcBaseのfriendとした。
>
>
> [3] RtcBase.cpp
> 1. sleep -> USLEEP
>
>
> [5] RtcInPort.h
> 1. m_Bufferの宣言位置変更→gccのWARNING(宣言の順番と初期化並びの順番が前後している)への対処
>
>
> [6] RtcManager.h
> 1. class LogEmitterのoperator()が戻り値を返していない。
> 適当な値(0)を返すように修正。
> しかし、この演算子にそもそも戻り値は必要なのか疑問。
> class LogEmitter
> : public RtcSyncCallback
> {
> public:
> LogEmitter(OutPortAny<TimedString>& port, TimedString& var)
> : m_OutPort(port), m_Var(var)
> {
> }
> virtual int operator()(const char* s)
> {
> m_Var.data = CORBA::string_dup(s);
> m_OutPort.write();
> return 0; // 追加
> }
>
>
> [7] RtcManager.cpp
> 1. usleep -> USLEEP
> 2. CPU負荷100%となる問題に対処
> 以下のように、2箇所のwhile内に、スリープを入れることで、ビジーループではなくなる。
> 暫定処置。本当にこれでよいかは要検討。
> void RtcManager::runManager()
> {
> // start POA manager
> m_pPOAManager->activate();
>
> if (CORBA::is_nil(m_pORB))
> {
> RTC_ERROR(("Invalid ORB pointer."));
> exit(1);
> }
> // m_pORB->run();
> while (g_mgrActive)
> {
> USLEEP(1000); // ビジーループ回避のためにスリープを入れる */
> if (m_pORB->work_pending()){
> m_pORB->perform_work();
> }
> }
> shutdown();
>
> while (m_pORB->work_pending())
> {
> USLEEP(1000); // ビジーループ回避のためにスリープを入れる */
> if (m_pORB->work_pending())
> m_pORB->perform_work();
> }
>
>
>
> [8] RtcModuleProfile.h
> 1. typedef 名を明示 → VC6の警告に対処
> typedef struct RtcModuleProfSpec {
> RtcModuleProfileType type;
> char* value;
> } RtcModuleProfSpec;
>
>
> [9] RtcModuleProfile.cpp
> 1. メソッドappendInPortProfile(),appendOutPortProfile()が戻り値を返していない。
> 適当な値(true)を返すように修正。
>
>
> [10] RtcNameComponent.cpp
> 1. メソッドpush()
> VC6の問題で、for(int i;...) ... for(int i; )とすると、
> intを同じスコープで再定義したことになる。int i; の定義をforの外に置く。
>
>
> [11] RtcNaming.cpp
> 1. メソッドpickupNode() が戻り値を返していない。
> 適当な値(true)を返すように修正。
>
>
> [12] RtcOutPort.h
> 1.VC6では、clock_gettimeがなく、ACE_OS::clock_gettimeの実装も何も処理をしていない。
>
> マクロ ACE_HAS_CLOCK_GETTIMEの定義部を以下のように修正。
> #if defined(_MSC_VER) && (_MSC_VER <= 1200) // VC6以前
> #else
> #define ACE_HAS_CLOCK_GETTIME // VC6ではclock_gettimeは存在しない。
> #endif
> メソッドwrite()を以下のように修正。
> #if defined (_MSC_VER) && (_MSC_VER <= 1200) // VC6以前
> ts = ACE_OS::gettimeofday();
> #else
> ACE_OS::clock_gettime(CLOCK_REALTIME, &ts);
> #endif
>
>
>
> [13] RtcRingBuffer.h
> 1. メソッドget_backがvirtualになっているのを、inlineに修正。
> 2.m_Oldestの宣言位置を最後に移動。→gccのWARNING(宣言の順番と初期化並びの順番が前後している)への対処
>
>
> [14] RtcSubscriber.h
> 1. メソッドupdate(), svc() のデフォルト実装が戻り値を返していない。
> 適当な値(trueと0)を返すように修正。
>
>
> [15] RtcSubscriber.cpp
> 1. メソッド int SubscriberPeriodic::svc(void)が戻り値を返していない。
> 適当な値(0)を返すように修正。
> 2. sleep(1); -> ACE_OS::sleep( ACE_Time_Value(1,0) );
>
>
> [16] RtcSystemLogger.h
> 1. VC6に存在しない定義を追加。
> #if defined(_MSC_VER) && (_MSC_VER <= 1200)
> # define LINE_MAX 2048
> # define vsnprintf _vsnprintf
> # define __restrict
> #endif
>
> 2. std::char_type, std::traits_type
> コンパイルエラー「char_type, traits_typeは'std' のメンバではありません。」
> が発生するため、以下のように修正。
> typedef _CharT char_type;
> typedef _Traits traits_type;
>
> 3. std::string::basic_string -> std::basic_string
> VC6には、std::string::basic_stringがないので以下のように修正。
> virtual int sync()
> {
> std::basic_string<_CharT> s(this->pbase(),
> this->pptr() - this->pbase());
>
>
> 4. ERRORマクロとの衝突。
> VC6では、WINGDI.HにマクロERRORが定義されている。
> #define ERROR 0
>
> 以下のように、ERRORを使っているところを、ERROR_に修正。
> #if defined(_MSC_VER) && (_MSC_VER <= 1200)
> enum {SILENT, ERROR_, WARN, INFO, NORMAL, DEBUG, TRACE, VERBOSE, PARANOID, MANDATORY };
> #else
> enum {SILENT, ERROR, WARN, INFO, NORMAL, DEBUG, TRACE, VERBOSE, PARANOID, MANDATORY };
> #endif
>
>
> 5. 自動変数の配列定義に定数が使われていない。
> メソッドgetFmtDate の以下の記述は、コンパイルエラー「定数式が必要です」が発生する。
> int maxsize(256);
> char buf[maxsize];
> 次のように修正。これは、VC6が正しいはず。
> const int maxsize(256);
> char buf[maxsize];
>
>
>
> ####################################################
> ちょっとした機能拡張
>
> [1] 構成ファイル(rtc.conf)の内容を、コンポーネントクラスで利用できるようにする。
>
> たとえば、
> rtc.confにシリアルポートの指定を以下のように追加しておいて、
> SeralPort /dev/ttyS0
>
> デバイスとシリアルポートで通信するコンポーネントのrtc_init_entryで、
> std::stirng port = getCofigValue("SerialPort");
> m_dev.Open( port );
> などと使えるようにしたい。
>
>
> 1. RtcConfigクラス
> (1) コンフィグレーション情報を取得できるように修正。
> 以下の関数を追加。
> /*!
> * @if jp
> * @brief コンフィグレーション情報取得
> * 任意のキーを指定してコンフィグレーション情報を取得する。
> * @param a_configKey キー文字列
> * @return 値文字列。見つからなかった場合は、空文字列となる。
> * @else
> * @endif
> */
> std::string getConfigValue(
> const std::string& a_configKey
> ) const
> {
> std::map<std::string, std::string>::const_iterator ci
> = m_Config.find(a_configKey);
> if( ci != m_Config.end() )
> {
> return ci->second;
> }
> else
> {
> return "";
> }
> }
>
> 2. RtcBaseクラス
> /*!
> * @brief 構成情報取得
> * 任意のキーを指定して構成情報を取得する。
> * @param a_configKey キー文字列
> * @return 値文字列。見つからなかった場合は、空文字列となる。
> */
> std::string getConfigValue(
> const std::string& a_configKey
> ) const
> {
> return m_pManager->getConfig().getConfigValue(a_configKey);
> }
>
>
>
openrtm-users メーリングリストの案内