C技巧:VC中编译、运行程序的知识点

发布时间:2011-08-29 共2页


  __try {
  _ioinit(); /* initialize lowio */
  _acmdln = (char *)GetCommandLineA(); /* get cmd line info */
  _aenvptr = (char *)__crtGetEnvironmentStringsA(); /* get environ info */
  _setargv();
  _setenvp();
  __initenv = _environ;
  mainret = main(__argc, __argv, _environ);
  exit(mainret);
  }
  __except ( _XcptFilter(GetExceptionCode(), GetExceptionInformation()) )
  {
  _exit( GetExceptionCode() ); /* Should never reach here */
  } /* end of try - except */
  } 如果使用MFC框架,WinMain也会被埋藏在MFC库中(APPMODUL.CPP):
  extern "C" int WINAPI
  _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  LPTSTR lpCmdLine, int nCmdShow)
  {
  // call shared/exported WinMain
  return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
  }
  对于ANSI版本,"_tWinMain"就是"WinMain";对于UINCODE版本,"_tWinMain"就是"wWinMain"。可参见afx.h:
  #ifdef _UNICODE
  #define _tmain wmain
  #define _tWinMain wWinMain
  #else
  #define _tmain main
  #define _tWinMain WinMain
  #endif
  全局C++对象的构造函数是在什么地方调用的?答案是在进入应用程序的Entry Point后,提示在调用main函数前的初始化操作中。所以MFC的theApp的构造函数是在_tWinMain之前调用的。
  4、不显示Console窗口的Console程序
  在默认情况下/subsystem 和/entry开关是匹配的,也就是:
  "console"对应"mainCRTStartup"或者"wmainCRTStartup"
  "windows"对应"WinMain"或者"wWinMain"
  我们可以通过手动修改的方法使他们不匹配。例如:
  #include "windows.h"
  #pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" ) // 设置入口地址
  void main(void)
  {
  MessageBox(NULL, "hello", "Notice", MB_OK);
  }
  这个Console程序就不会显示Console窗口。如果选/MLd的话,这个程序只需要链接LIBCD.LIB user32.lib kernel32.lib。
  其实如果不想看到Console窗口,还有一个更直接的方法:那就是直接在EXE文件中将PE文件头的Subsystem从3改成2。在EXE文件中,PE文件头的偏移地址是0x3c,Subsystem是一个WORD,它在PE文件头中的偏移是0x5c。
  5、MFC的库文件
  MFC的库可以静态链接,也可以动态链接。静态库和动态库又有Debug和Release,ANSI和Unicode版本之分。
  静态MFC库主要有:
  ANSI Debug NAFXCWD.LIB
  ANSI Release NAFXCW.LIB
  Unicode Debug UAFXCWD.LIB
  Unicode Release UAFXCW.LIB
  动态链接库主要有;
  ANSI Debug MFCxxD.LIB (core,MFCxxD.DLL),
  MFCOxxD.LIB (OLE,MFCOxxD.DLL),
  MFCDxxD.LIB (database,MFCDxxD.DLL),
  MFCNxxD.LIB (network,MFCNxxD.DLL),
  MFCSxxD.LIB (static)
  ANSI Release MFCxx.LIB (combined,MFCxx.DLL)
  MFCSxx.LIB (static)
  Unicode Debug MFCxxUD.LIB (core,MFCxxUD.DLL),
  MFCOxxUD.LIB (OLE,MFCOxxUD.DLL),
  MFCDxxUD.LIB (database,MFCDxxUD.DLL),
  MFCNxxUD.LIB (network,MFCNxxUD.DLL),
  MFCSxxUD.LIB (static)
  Unicode Release MFCxxU.DLL (combined,MFCxxU.DLL),
  MFCSxxU.LIB (static)
  上面的LIB文件除了MFCSxx(D、U、UD).LIB以外都是导入库。
  MFC动态链接库版本也需要静态链接一些文件,这些文件就放在MFCSxx(D、U、UD).LIB中。例如包含_tWinMain的appmodul.cpp。
  6、结束语
  研究这些问题的动机是想弄清楚我们的程序是如何装载、运行的。但是,由于Windows不是开源平台,提示只能研究到PE文件(Windows上可执行文件的格式)。entry point、subsystem都是PE文件头的一部分。
  Windows在进入PE文件的entry point之前做了些什么,就看不到了,只能概推测:应该是创建一个进程,装载PE文件和所有需要的DLL,初始化C变量,然后从某个起点函数开始运行。不同的subsystem,应该有不同的起点。调用这个起点函数时应该传入PE文件的entry point地址。

百分百考试网 考试宝典

立即免费试用