程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> ACE服務端編程4:ACE跨平台之運行時初始化和關閉,ace服務端

ACE服務端編程4:ACE跨平台之運行時初始化和關閉,ace服務端

編輯:C++入門知識

ACE服務端編程4:ACE跨平台之運行時初始化和關閉,ace服務端


參考APG裡的說法:平台差異及不兼容性的一個特別的方面,是對象的運行時初始化和程序關閉時這些對象的相應析構。

ACE為了明確管理對象的清理,定義了ACE_Object_Manager類,這個類不僅涉及到對象的管理,還與ACE庫的初始化與關閉相關。

ACE中應用了大量的設計模式,本篇順便研究ACE的程序入口函數替換機制分析。

ACE庫的初始化與關閉


應用要確保在使用ACE庫時正確的初始化和關閉,有以下兩種常用方式:

1、使用ACE_TMAIN宏作為程序入口函數;

2、使用ACE::init()和ACE::fini()明確初始化和關閉ACE庫。

ACE_TMAIN宏會對程序入口函數進行替換,已在程序執行前和執行後加入初始化代碼,對ACE程序入口函數替換機制分析,可以使用編譯器展開ACE_TMAIN的代碼:

int ace_main_i (int, char *[]);  
__declspec (dllimport) int ace_os_main_i (ACE_Main_Base&, int, char *[]); 
class ACE_Main : public ACE_Main_Base 
{
int run_i (int, char *[]);}; 
inline int ACE_Main::run_i (int argc, char *argv[]) { return ace_main_i (argc, argv); }  
int main (int argc, char *argv[])
{ 
ACE_Main m; return m.run (argc, argv); 
} 
int ace_main_i (int argc, ACE_TCHAR * argv[])
{
	
	return 0;
}

可以看到真正的main函數體被替換為:ACE_Main m; return m.run (argc, argv);而程序代碼被包括到ace_main_i函數中。

ACE_Main的實例對象m是一個main函數內的棧對象,在main函數開始構造,在函數的結束析構。

ACE_Main類是一個生成類,繼承自ACE_Main_Base類,調用其run函數。

ACE_Main_Base在ace/Os_main.h類中定義,代碼片段如下:

ACE_Main_Base::ACE_Main_Base ()
{
  ACE::init ();
}

ACE_Main_Base::~ACE_Main_Base ()
{
  ACE::fini ();
}

int ACE_Main_Base::run (int argc, char *argv[])
{
  return this->run_i (argc, argv);
}

可以看到其構造函數和析構函數也分別通過ACE::init()和ACE::fini()初始化和關閉ACE庫。

研究ACE的宏展開也學習一種入口函數替換機制。

跟蹤ACE::init()


通過展開ACE_TMAIN宏,發現最終還是在main函數的開始初調用了ACE::init函數,這個函數定義在ace/Init_Ace.cpp中:

int
ACE::init (void)
{
  // Don't use ACE_TRACE, because Object_Manager might not have been
  // instantiated yet.
  // ACE_TRACE ("ACE::init");

  ++ACE::init_fini_count_;

  return ACE_Object_Manager::instance ()->init ();
}

init的函數體非常簡單,就是初始化ACE_Object_Manager,也就回到本文開始的主體:這個類不僅涉及到對象的管理,還與ACE庫的初始化與關閉相關。

fini函數與此類似,調用了ACE_Object_Manager的清理函數,有興趣的可以查看源代碼。

ACE_Object_Manager


ACE_Object_Manager類之所以與ACE庫的初始化和關閉相關,是因為ACE_Object_Manager不僅可以幫助應用能按正確的方式清理對象,ACE庫內部的對象管理也依賴於ACE_Object_Manager。

至於ACE_Object_Manager的init函數中的代碼可以不必過多深究,主要是實例化一組ACE對象,用以給ACE的內部機制提供支持,並在關閉時銷毀這些對象。

ACE_Object_Manager提供了at_exit函數,允許應用向其登記對象,並在關閉時會以登記次序相反的次序銷毀所登記的對象。

向ACE_Object_Manager登記的對象必須繼承自ACE_Cleanup,並實現cleanup()方法進行清理工作;對於基本類型的對象可以使用at_exit的重載函數傳遞一個ACE_CLEANUP_FUNC的回調函數。

ACE_Object_Manager的API:http://www.dre.vanderbilt.edu/Doxygen/6.0.0/html/libace-doc/a00355.html

要保證ACE_Object_Manager能夠正確的清理對象,必須滿足以下兩條:

1、永遠不要直接調用exit(),讓main函數通過return返回(推薦閱讀:exit & abort & 析構 & 異常 );

2、確保ACE_Object_Manager成功初始化。

ACE非常有名的單例模式也是關聯到ACE_Object_Manager,後期有機會單獨寫出來。


記錄,為更好的自己!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved