C技巧:VC中编译、运行程序的知识点(3)
' Q! B% G+ }% D__try { & g4 o7 y. B- g, E4 I* i- C( @
_ioinit(); /* initialize lowio */
7 l) ]3 o) `2 i/ @5 n _acmdln = (char *)GetCommandLineA(); /* get cmd line info */
8 m* S+ G0 `+ B; B* @' c1 V _aenvptr = (char *)__crtGetEnvironmentStringsA(); /* get environ info */3 O% a G- i% {/ g$ l
_setargv();
! g1 d0 j3 p, m$ k4 q9 A _setenvp();8 @! d z+ I0 i. x: K0 C8 |
__initenv = _environ;+ ^7 R D1 h. e! w" s3 ?
mainret = main(__argc, __argv, _environ);% j, g# l" |, E
exit(mainret);9 x# N0 P( }0 u; v" O
} T3 A: R, e c" f
__except ( _XcptFilter(GetExceptionCode(), GetExceptionInformation()) )
: V; u, w! h2 [2 A2 a% y {; K% K; \# C' I( B9 j
_exit( GetExceptionCode() ); /* Should never reach here */& b! N) e( T% x: i% P9 a
} /* end of try - except */# l6 j$ N% g, }7 x& _% J7 s
} 如果使用MFC框架,WinMain也会被埋藏在MFC库中(APPMODUL.CPP):
3 L2 P# q/ A8 f9 I; E, I8 W$ l extern "C" int WINAPI
5 Y" ^7 y' r R+ ^$ h _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,1 q$ o4 W7 p: G1 ]; f
LPTSTR lpCmdLine, int nCmdShow)8 [: x/ }: f8 }$ L6 c; F
{
% P8 Y+ B1 I; e" a- \( |! E6 \ // call shared/exported WinMain
, t6 c( o% B1 ~" M return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);4 U% U5 l0 j% m. a/ f0 v+ L5 ]. [
}
$ D) w5 u% }& U0 Q* \1 u, J 对于ANSI版本,"_tWinMain"就是"WinMain";对于UINCODE版本,"_tWinMain"就是"wWinMain"。可参见afx.h:
% k% i. ^6 `4 S$ G! G4 Y #ifdef _UNICODE) e; g, G/ C) d$ I9 l6 _9 N$ _
#define _tmain wmain, D$ M3 R' N, \4 n- i
#define _tWinMain wWinMain7 Z; ~9 g) b+ [: F" C
#else( v- j |: d6 Y( g" V/ f' X9 u
#define _tmain main ^" l: h4 }7 c( C# u
#define _tWinMain WinMain, a% R# B: u$ v
#endif
% ]( Z- N6 m3 B1 K5 F$ H6 P 全局C++对象的构造函数是在什么地方调用的?答案是在进入应用程序的Entry Point后,考试大提示在调用main函数前的初始化操作中。所以MFC的theApp的构造函数是在_tWinMain之前调用的。7 I4 r+ S7 t4 z
4、不显示Console窗口的Console程序
- j' Q g$ ~+ I* ^' p3 {& f 在默认情况下/subsystem 和/entry开关是匹配的,也就是:
7 E* j: R+ R' T4 L2 ] "console"对应"mainCRTStartup"或者"wmainCRTStartup"
. R$ l$ d% b8 _& v! L) I3 K "windows"对应"WinMain"或者"wWinMain"
7 A1 r1 d, [/ Z+ P9 z2 k 我们可以通过手动修改的方法使他们不匹配。例如:* {! M) O! E: P8 Y& u; Y. \
#include "windows.h"
' A8 i5 v. o R4 _6 p7 j #pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" ) // 设置入口地址/ J9 p u7 k. L$ F1 N. l+ Z+ f
void main(void)
+ c, |( D2 w% V1 ?7 \ {
2 h( W( F0 a/ N& _3 I/ w MessageBox(NULL, "hello", "Notice", MB_OK);
1 z F. l& T" _ }
{$ F# E* m# B, H 这个Console程序就不会显示Console窗口。如果选/MLd的话,这个程序只需要链接LIBCD.LIB user32.lib kernel32.lib。4 n: n% N& `2 H o n
其实如果不想看到Console窗口,还有一个更直接的方法:那就是直接在EXE文件中将PE文件头的Subsystem从3改成2。在EXE文件中,PE文件头的偏移地址是0x3c,Subsystem是一个WORD,它在PE文件头中的偏移是0x5c。 |