ACE程序入口函数替换机制分析

来源:互联网 发布:空军工程大学淘宝地址 编辑:程序博客网 时间:2024/05/19 23:28

ACE程序入口函数替换机制分析(收藏)

 
ACE程序入口函数替换机制分析
(hardcorn 写于2005.10.27)


我们从一个ACE例子进行分析:

ACE程序中的ACE_TMAIN宏说明:
大家注意看我代码中的注释

先看原代码:
//--------------------------------------
//copy from: ACE_ROOT/ace/OS_main.h
//ACE_TMAIN define
#     define ACE_TMAIN /
ace_tmain_i (int, ACE_TCHAR *[]); / //***我们自己的代码会添加到这个函数中,进行调用
ACE_Export int ace_os_wintmain_i (ACE_Main_Base&, HINSTANCE, HINSTANCE, LPWSTR, int);  /* forward declaration */ /
class ACE_Main : public ACE_Main_Base {int run_i (int argc, ACE_TCHAR *argv[]);}; /
inline int ACE_Main::run_i (int argc, ACE_TCHAR *argv[])  /
{ /
  return ace_tmain_i (argc, argv); / //***调用我们编写的代码
} /
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) / //***程序真实的入口
{ /
  ACE_Main m; / //***定义一个ACE_Main对象,并传给ace_os_wintmain_i,在ace_os_wintmain_i中,会调用m.run_i()
  return ace_os_wintmain_i (m, hInstance, hPrevInstance, lpCmdLine, nCmdShow); /
} /
int ace_tmain_i //***ACE为们提供一个函数头,函数体由我们自己来写。
//ACE_TMAIN end.
//-------------------------------------

//-------------------------------------
// copy form ACE_ROOT/ace/OS_main.cpp
//ace_os_wintmain_i define 
int WINAPI ace_os_wintmain_i (ACE_Main_Base &mbase, HINSTANCE hInstance,
                              HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
{
  ACE_TCHAR cmdline[1024];
  ACE_OS::strcpy (cmdline, ACE_LIB_TEXT ("program "));
  ACE_OS::strcat (cmdline, lpCmdLine);
  ACE_ARGV ce_argv (cmdline);
  ACE::init (); //***注意,对ACE环境时行初始化
  ACE_MAIN_OBJECT_MANAGER
  
//***注意下边这行代码。mbase.run()中,会去调用我们在外边定义的run_i(),这是一个虚函数
//***而run_i()中会调用ace_tmain_i(),这才是我们要自己要运行的代码
  int i = mbase.run (ce_argv.argc (), ce_argv.argv ());

  ACE::fini (); //***注意,释放ACE环境
  return i;
}
//ace_os_wintmain_i end
//-------------------------------------


例子:
//我写一ACE的代码,并将宏进行还原:
//ACE代码:
int ACE_TMAIN(int args, ACE_TCHAR *argv[])
{
int a = 0;
int b = 1;
a = a + b;
}
//将宏还原后的真实代码:
int /*ACE_TMAIN strat*/ ace_tmain_i (int, ACE_TCHAR *[]); 

//注:ace_os_wintmain_i是从ace库中导出的函数,直接用函数体来代替这个声明:
//ACE_Export int ace_os_wintmain_i (ACE_Main_Base&, HINSTANCE, HINSTANCE, LPWSTR, int);
int WINAPI ace_os_wintmain_i (ACE_Main_Base &mbase, HINSTANCE hInstance,
                              HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
{
  ACE_TCHAR cmdline[1024];
  ACE_OS::strcpy (cmdline, ACE_LIB_TEXT ("program "));
  ACE_OS::strcat (cmdline, lpCmdLine);
  ACE_ARGV ce_argv (cmdline);
  ACE::init ();
  ACE_MAIN_OBJECT_MANAGER
  int i = mbase.run (ce_argv.argc (), ce_argv.argv ());
  ACE::fini ();
  return i;
}

class ACE_Main : public ACE_Main_Base 
{
int run_i (int argc, ACE_TCHAR *argv[]);
}; 

inline int ACE_Main::run_i (int argc, ACE_TCHAR *argv[])  

   return ace_tmain_i (argc, argv); 


int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) 

  ACE_Main m; 
  return ace_os_wintmain_i (m, hInstance, hPrevInstance, lpCmdLine, nCmdShow); 


int ace_tmain_i /*ACE_TMAIN end*/ ( int args, ACE_TCHAR* argv[])
{
int a = 0;
int b = 1;
a = a + b;
}
//end

WinMain  -call-> ace_os_wintmain_i [进行ACE环境的初始] -call-> ACE_Main_Base::run() -call->ACE_Main::run_i()  -call-> ace_tmain_i[运行我们自己的代码]
WinMain  <-ret- ace_os_wintmain_i [释放ACE环境] <-ret- ACE_Main::run_i()  <-ret- ace_tmain_i

还有,我上边列出来的ACE_TMAIN只是其中之一,ACE做了好几个程序入口函数的宏替换:
如:main,wmain

说明:
ACE对我们的程序入口,进行到替换. 在程序启动和退出时,做了一些初始化工作。
其中最主要的工作就是: ACE::init() 和 ACE::fini();

再说明我MFC吧,MFC将程序入口,包在了CWinApp类中。所以ACE没有办法对其进行修改。
也就没有办法在MFC中做一些“自动”的初始化和释放工作; 那么这个工作就只有我们自己完成了...
所以在MFC的工程中使用ACE,就得自己调用初始化: ACE::init(); 和释放:ACE::fini()
如果不调!!!呵呵。那就只好等着出错了。:)


转贴地址:http://blog.sina.com.cn/s/blog_54c746f4010009cm.html