VC++ 编译设置

1、Run-Time   Library
Run-Time   Library是编译器提供的标准库,提供一些基本的库函数和系统调用。
我们一般使用的Run-Time   Library是C   Run-Time   Libraries。当然也有Standard   C++   libraries。  
C   Run-Time   Libraries实现ANSI   C的标准库。VC安装目录的CRT目录有C   Run-Time库的大部分源代码。  
C   Run-Time   Libraries有静态库版本,也有动态链接库版本;有单线程版本,也有多线程版本;还有调试和非调试版本。
可以在 "project "- "settings "- "C/C++ "- "Code   Generation "中选择Run-Time   Library的版本。

动态链接库版本:
/MD   Multithreaded   DLL   使用导入库MSVCRT.LIB
/MDd   Debug   Multithreaded   DLL   使用导入库MSVCRTD.LIB

静态库版本:
/ML   Single-Threaded   使用静态库LIBC.LIB  
/MLd   Debug   Single-Threaded   使用静态库LIBCD.LIB
/MT   Multithreaded   使用静态库LIBCMT.LIB
/MTd   Debug   Multithreaded   使用静态库LIBCMTD.LIB

C   Run-Time   Library的标准io部分与操作系统的关系很密切,在Windows上,CRT的io部分代码只是一个包装,底层要用到操作系统内核 kernel32.dll中的函数,在编译时使用导入库kernel32.lib。这也就是为什么在嵌入式环境中,我们一般不能直接使用C标准库。
在Linux环境当然也有C标准库,例如:
ld   -o   output   /lib/crt0.o   hello.o   -lc
参数 "-lc "就是在引用C标准库libc.a。猜一猜 "-lm "引用哪个库文件?

2、常见的编译参数
VC建立项目时总会定义 "Win32 "。控制台程序会定义 "_CONSOLE ",否则会定义 "_WINDOWS "。Debug版定义 "_DEBUG ",Release版定义 "NDEBUG "

与MFC   DLL有关的编译常数包括:
_WINDLL   表示要做一个用到MFC的DLL
_USRDLL   表示做一个用户DLL(相对MFC扩展DLL而言)  
_AFXDLL   表示使用MFC动态链接库
_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产生静态库。

3、subsystem和可执行文件的启动
LINK的时候需要指定/subsystem,这个链接选项告诉Windows如何运行可执行文件。
控制台程序是/subsystem: "console "
其它程序一般都是/subsystem: "windows   "

将   subsystem   选成 "console "后,Windows在进入可执行文件的代码前(如mainCRTStartup),就会产生一个控制台窗口。
如果选择 "windows ",操作系统就不产生console窗口,该类型应用程序的窗口由用户自己创建。

可执行文件都有一个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是WinMainCRTStartup(ANSI)或wWinMainCRTStartup(UINCODE),即:
/subsystem: "windows "   /entry: "WinMainCRTStartup "   (ANSI)
/sbusystem: "windows "   /entry: "wWinMainCRTStartup "   (UINCODE)
WinMainCRTStartup   或   wWinMainCRTStartup   会调用   WinMain   或   wWinMain。

如果使用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);
}
"_t "是一个宏,对于ANSI版本, "_tWinMain "就是 "WinMain ";对于UINCODE版本, "_tWinMain "就是 "wWinMain "。

全局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。

5、VC中缺省库冲突的解决
VC的编译器在编译程序时有两个习惯:
a、在从头开始编译时,将源文件名按字母排序后,依次处理;
b、一边编译一边决定需要哪些缺省库。  
它的这些习惯有时会造成奇怪的编译错误,例如项目中有两个文件:
charutil.c
gbnni.cpp
其中gbnni.cpp用到了MFC库。

它老兄当然是先处理charutil.c,然后觉得需要link一个C   Runtime库,根据项目设置选择了LIBCMTD.lib。
然后又处理gbnni.cpp,因为要用MFC,又决定要link   nafxcwd.lib。
最后link的时候,就会出现以下冲突:
nafxcwd.lib(afxmem.obj)   :   error   LNK2005:   "void   __cdecl   operator   delete(void   *) "   (??3@YAXPAX@Z)   already   defined   in   LIBCMTD.lib(dbgdel.obj)
其实,必须先链接nafxcwd.lib,再链接LIBCMTD.lib,所以一个更简单的方法是在settings-link-input中设置nafxcwd.libLIBCMTD.lib
即指定库的顺序。

解决这类问题有两个办法。
a、让项目的第一个文件包含MFC的头文件,这样编译器就不会想到找C   Runtime库。这样就要把c文件改成cpp了。
b、将需要link   C   Runtime库的文件的名字改大一些,让它排在后面。
使用IDE当然很方便,但既然使用了别人写的工具,有时就不得不琢磨、迁就它的习性。

 

 

 

使用dll,采用显式声明时,可以用如下三种方式添加lib:

a.可以到“project”菜单下选择“Add   To   Project”,“Files”,然后把lib文件加进来。
b.也可以设置工程选项:到“project”菜单下选择“Settings”,然后选择“link”选项卡,在其中的Object/library   Modules中填入“yourLib.lib”
        c.还有一种方法,直接在CMyDlg.cpp文件开始处添加一句预编译指令:
                  #pragma   comment(lib,”   yourLib.lib”)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值