青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

posts - 319, comments - 22, trackbacks - 0, articles - 11
  C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

在VC中編譯、運行程序的小知識點

Posted on 2011-05-12 22:06 RTY 閱讀(540) 評論(0)  編輯 收藏 引用 所屬分類: 編程常識C/C++轉載隨筆

1、Run-Time Library

Run-Time Library是編譯器提供的標準庫,提供一些基本的庫函數(shù)和系統(tǒng)調用。
我們一般使用的Run-Time Library是C Run-Time Libraries。當然也有Standard C++ libraries。 
C Run-Time Libraries實現(xiàn)ANSI C的標準庫。VC安裝目錄的CRT目錄有C Run-Time庫的大部分源代碼。

C Run-Time Libraries有靜態(tài)庫版本,也有動態(tài)鏈接庫版本;有單線程版本,也有多線程版本;還有調試和非調試版本。
可以在"project"-"settings"-"C/C++"-"Code Generation"中選擇Run-Time Library的版本。

動態(tài)鏈接庫版本:
/MD Multithreaded DLL 使用導入庫MSVCRT.LIB
/MDd Debug Multithreaded DLL 使用導入庫MSVCRTD.LIB

靜態(tài)庫版本:
/ML Single-Threaded 使用靜態(tài)庫LIBC.LIB 
/MLd Debug Single-Threaded 使用靜態(tài)庫LIBCD.LIB
/MT Multithreaded 使用靜態(tài)庫LIBCMT.LIB
/MTd Debug Multithreaded 使用靜態(tài)庫LIBCMTD.LIB

C Run-Time Library的標準io部分與操作系統(tǒng)的關系很密切,在Windows上,CRT的io部分代碼只是一個包裝,底層要用到操作系統(tǒng)內核kernel32.dll中的函數(shù),在編譯時使用導入庫kernel32.lib。這也就是為什么在嵌入式環(huán)境中,我們一般不能直接使用C標準庫。
在Linux環(huán)境當然也有C標準庫,例如:
ld -o output /lib/crt0.o hello.o -lc
參數(shù)"-lc"就是在引用C標準庫libc.a。猜一猜"-lm"引用哪個庫文件?

2、常見的編譯參數(shù)

VC建立項目時總會定義"Win32"。控制臺程序會定義"_CONSOLE",否則會定義"_WINDOWS"。Debug版定義"_DEBUG",Release版定義"NDEBUG"

 

與MFC DLL有關的編譯常數(shù)包括:
_WINDLL 表示要做一個用到MFC的DLL
_USRDLL 表示做一個用戶DLL(相對MFC擴展DLL而言) 
_AFXDLL 表示使用MFC動態(tài)鏈接庫
_AFXEXT 表示要做一個MFC擴展DLL
所以:
Regular, statically linked to MFC _WINDLL,_USRDLL 
Regular, using the shared MFC DLL _WINDLL,_USRDLL,_AFXDLL
Extension DLL _WINDLL,_AFXDLL,_AFXEXT

CL.EXE編譯所有源文件,LINK.EXE鏈接EXE和DLL,LIB.EXE產生靜態(tài)庫。

3、subsystem和可執(zhí)行文件的啟動

LINK的時候需要指定/subsystem,這個鏈接選項告訴Windows如何運行可執(zhí)行文件。
控制臺程序是/subsystem:"console"
其它程序一般都是/subsystem:"windows "

 

將 subsystem 選成"console"后,Windows在進入可執(zhí)行文件的代碼前(如mainCRTStartup),就會產生一個控制臺窗口。
如果選擇"windows",操作系統(tǒng)就不產生console窗口,該類型應用程序的窗口由用戶自己創(chuàng)建。

可執(zhí)行文件都有一個Entry Point,LINK時可以用/entry指定。缺省情況下,如果subsystem是“console”,Entry Point是 mainCRTStartup(ANSI)或wmainCRTStartuup(UNICODE),即:
/subsystem:"console" /entry:"mainCRTStartup" (ANSI)
/subsystem:"console" /entry:"wmainCRTStartuup" (UNICODE)
mainCRTStartup 或 wmainCRTStartuup 會調用main或wmain。
值得一提的是,在進入應用程序的Entry Point前,Windows的裝載器已經做過C變量的初始化,有初值的全局變量擁有了它們的初值,沒有初值的變量被設為0。

如果subsystem是“windows”,Entry Point是WinMain(ANSI)或wWinMain(UINCODE),即:
/subsystem:"windows" /entry:"WinMainCRTStartup" (ANSI)
/sbusystem:"windows" /entry:"wWinMainCRTStartup" (UINCODE)
WinMainCRTStartup 或 wWinMainCRTStartup 會調用 WinMain 或 wWinMain。

這些入口點函數(shù),在CRT目錄都可以看到源代碼,例如(為了簡潔,我刪除了原代碼的一些條件編譯):

void mainCRTStartup(void)
{
        int mainret;

        /* Get the full Win32 version */
        _osver = GetVersion();
        _winminor = (_osver >> 8) & 0x00FF ;
        _winmajor = _osver & 0x00FF ;
        _winver = (_winmajor << 8) + _winminor;
        _osver = (_osver >> 16) & 0x00FFFF ;

#ifdef _MT
        if ( !_heap_init(1) )               /* initialize heap */
#else  /* _MT */
        if ( !_heap_init(0) )               /* initialize heap */
#endif  /* _MT */
            fast_error_exit(_RT_HEAPINIT);  /* write message and die */

#ifdef _MT
        if( !_mtinit() )                    /* initialize multi-thread */
            fast_error_exit(_RT_THREAD);    /* write message and die */
#endif  /* _MT */

        __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++對象的構造函數(shù)是在什么地方調用的?答案是在進入應用程序的Entry Point后,在調用main函數(shù)前的初始化操作中。所以MFC的theApp的構造函數(shù)是在_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的庫可以靜態(tài)鏈接,也可以動態(tài)鏈接。靜態(tài)庫和動態(tài)庫又有Debug和Release,ANSI和Unicode版本之分。

 

靜態(tài)MFC庫主要有:
ANSI Debug NAFXCWD.LIB
ANSI Release NAFXCW.LIB
Unicode Debug UAFXCWD.LIB
Unicode Release UAFXCW.LIB 

動態(tài)鏈接庫主要有;
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動態(tài)鏈接庫版本也需要靜態(tài)鏈接一些文件,這些文件就放在MFCSxx(D、U、UD).LIB中。例如包含_tWinMain的appmodul.cpp。

6、結束語

研究這些問題的動機是想弄清楚我們的程序是如何裝載、運行的。但是,由于Windows不是開源平臺,我也只能研究到PE文件(Windows上可執(zhí)行文件的格式)。entry point、subsystem都是PE文件頭的一部分。

Windows在進入PE文件的entry point之前做了些什么,就看不到了,只能大概推測:應該是創(chuàng)建一個進程,裝載PE文件和所有需要的DLL,初始化C變量,然后從某個起點函數(shù)開始運行。不同的subsystem,應該有不同的起點。調用這個起點函數(shù)時應該傳入PE文件的entry point地址。

 

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久综合久久综合久久综合| 久久精品日产第一区二区三区 | 麻豆精品传媒视频| 国产日韩欧美一区二区三区四区| 亚洲一区二区三区三| 亚洲视频狠狠| 国产麻豆91精品| 久久综合久久综合九色| 久久影院午夜论| 99riav国产精品| 在线视频你懂得一区二区三区| 国产精品欧美一区喷水| 久久久亚洲欧洲日产国码αv| 久久精品女人的天堂av| 亚洲黄一区二区三区| 亚洲欧洲一区二区三区| 欧美全黄视频| 久久精品99久久香蕉国产色戒| 久久www成人_看片免费不卡| 亚洲高清二区| 一区二区三区国产在线| 国产午夜精品全部视频在线播放 | 久久精品国产亚洲一区二区| 亚洲欧美制服中文字幕| 一区二区亚洲精品| 亚洲美女电影在线| 国产一区二区黄| 亚洲国产高清自拍| 国产日韩欧美精品一区| 亚洲国产精品ⅴa在线观看| 国产精品高潮久久| 欧美岛国在线观看| 国产精品一区二区女厕厕| 欧美激情中文字幕乱码免费| 国产精品第三页| 欧美成人一区二区三区片免费| 欧美婷婷在线| 欧美激情性爽国产精品17p| 国产精品久久国产愉拍| 亚洲国产精品精华液2区45| 国产欧美日韩三区| 日韩视频永久免费| 亚洲第一成人在线| 香蕉亚洲视频| 亚洲欧美福利一区二区| 欧美国产亚洲视频| 免费高清在线视频一区·| 欧美午夜一区二区福利视频| 亚洲电影天堂av| 影音先锋久久| 欧美一区二区三区啪啪| 先锋影音国产一区| 欧美日韩一视频区二区| 亚洲国产精选| 亚洲国产黄色| 久久久久一区二区三区| 久久精品99国产精品| 国产精品成人播放| 99国产麻豆精品| 艳妇臀荡乳欲伦亚洲一区| 美女性感视频久久久| 麻豆久久久9性大片| 韩日欧美一区二区| 欧美一区国产一区| 久久久噜噜噜久久狠狠50岁| 国产日韩欧美亚洲一区| 亚洲欧美www| 久久激情婷婷| 国语精品一区| 久久久久久久激情视频| 美女主播一区| 亚洲激情在线| 欧美精品在线视频| 日韩视频精品在线| 亚洲香蕉伊综合在人在线视看| 欧美日韩裸体免费视频| 夜夜精品视频| 羞羞视频在线观看欧美| 国产午夜精品久久| 久久久久久久久蜜桃| 免费在线欧美黄色| 亚洲精品久久久久| 欧美日韩午夜激情| 亚洲欧美日韩国产另类专区| 久久国产精品久久国产精品| 国产一区二区三区四区hd| 久久精品一区二区国产| 亚洲电影免费观看高清| 亚洲午夜激情网站| 国产日韩精品一区二区| 久久久噜噜噜久久| 亚洲精品美女在线观看| 亚洲欧美视频在线观看视频| 国产精品日韩一区二区三区| 久久精品中文字幕免费mv| 亚洲成人在线视频播放 | 欧美四级在线观看| 亚洲一级黄色| 欧美成人免费在线| 亚洲一区二区综合| 一区二区三区在线看| 欧美韩日一区二区三区| 亚洲一区二区三区视频| 女女同性精品视频| 国产精品99久久久久久白浆小说| 国产婷婷97碰碰久久人人蜜臀| 美女福利精品视频| 亚洲欧美日韩精品一区二区| 欧美刺激性大交免费视频| 亚洲综合国产| 亚洲激情专区| 国产精品视频大全| 欧美国产精品久久| 欧美自拍丝袜亚洲| 一区二区三区成人| 欧美激情视频在线播放 | 在线播放亚洲一区| 欧美色图天堂网| 免费成人在线观看视频| 亚洲欧美成人网| 亚洲精品影视| 欧美国产精品专区| 久久久av毛片精品| 亚洲制服av| 日韩香蕉视频| 亚洲国产精品va在看黑人| 国产精品素人视频| 欧美日韩日日骚| 欧美电影免费观看| 久久综合色影院| 久久国产主播精品| 亚洲免费在线观看| 99在线热播精品免费| 亚洲国产日韩一区二区| 男人插女人欧美| 久久午夜精品一区二区| 欧美在线免费看| 午夜精品一区二区三区在线播放 | 亚洲午夜精品在线| 亚洲日本成人在线观看| 亚洲国产精品女人久久久| 国内久久精品视频| 国产欧美三级| 国产香蕉久久精品综合网| 国产精品一卡二卡| 国产情侣久久| 国产综合色精品一区二区三区| 国产美女精品| 国产一区二区三区在线观看免费 | 国产精品毛片va一区二区三区 | 一区二区三区福利| 亚洲精品一二三| 日韩午夜激情av| 中文亚洲欧美| 亚洲欧美日韩国产中文在线| 亚洲免费视频网站| 久久av免费一区| 久久综合五月天婷婷伊人| 免费久久99精品国产自| 亚洲国产成人不卡| 亚洲精选一区二区| 亚洲一区二区三区四区五区黄| 亚洲伊人网站| 久久精品成人一区二区三区| 久久综合伊人77777麻豆| 农夫在线精品视频免费观看| 欧美国产高潮xxxx1819| 欧美日韩在线另类| 国产亚洲精品一区二区| 亚洲第一精品久久忘忧草社区| 亚洲精品日韩欧美| 亚洲欧美视频一区二区三区| 久久久999国产| 亚洲福利视频免费观看| 妖精视频成人观看www| 欧美亚洲视频在线观看| 久久这里只有| 欧美性猛交xxxx乱大交退制版| 国产日韩欧美一区| 亚洲毛片一区二区| 性色一区二区三区| 欧美国产日韩免费| 亚洲视频在线一区| 乱中年女人伦av一区二区| 欧美日韩综合| 亚洲成人中文| 午夜精品一区二区三区电影天堂| 米奇777超碰欧美日韩亚洲| 日韩亚洲不卡在线| 久久国产一区二区| 欧美图区在线视频| 亚洲国产高清一区二区三区| 亚洲欧美视频在线观看| 亚洲高清二区| 午夜精品久久久久久久99黑人| 欧美国产日韩一区二区| 国内精品久久久久久久影视麻豆 | 亚洲影院免费| 欧美二区在线| 久久精品1区|