[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 メーリングリストの案内