/*转载请注明出自 听风独奏 www.GbcDbj.com */
Windows应用程序分为GUI(Graphical User Interface)和CUI(Console User Interface)程序,很多人却会误认为Windows程序就是GUI程序。
很多初学者使用Microsoft Visual Studio 编写程序时经常会错误地创建程序类型,导致出现”unresolved external symbol”的错误,原因在于Visual C++的链接器开关设置问题。该开关在: 项目属性->链接器->系统->子系统。
首先,创建GUI程序,对应开关设置为: WINDOWS(/SUBSYSTEM:WINDOWS),创建CUI程序则对应:控制台(/SUBSYSTEM:CONSOLE),都已默认选择的了。
其次,对应GUI程序的入口点函数为_tWinMain,而CUI则为mian。然而系统并不真正调用这两个入口点函数,他们是由”可执行文件的启动函数调用”,而启动函数系系统根据链接器开关的设置来选择加载哪一个启动函数,启动函数与入口点函数之间的调用必须正确对应,认识这一点很重要!
函数类型和入口点函数,启动函数之间的对应关系:
应用程序类型 - 入口点函数 -嵌入的可执行文件启动函数
ANSIC版本的GUI程序 - _tWinMain(WinMain) - WinMainCRTStartup
UNICODE版本的GUI程序 - _tWinMain(WinMain) - wWinMainCRTStartup
ANSIC版本的CUI程序 - _tmain(Main) - mainCRTStartup
UNICODE版本的CUI程序 - _tmain(Main) - mainCRTStartup
现在认识清楚了错误原因后,我们来一起分析下错误和如何去修改:
现在假如一个程序员想在控制台程序下调用MFC和Win32API函数时,他会创建一个Win32应用项目,即GUI程序,然后编写main入口点函数。
首先链接可执行文件时候,链接器会根据链接器子系统开关设置选择正确的启动函数,由于GUI程序对应开关(默认)为WINDOWS(/SUBSYSTEM:WINDOWS),则链接器根据他加载WinMainCRTStartup或者wWinMainCRTStartup,然后会寻找WinMain或者wWinMain入口点函数,并且由启动函数调用。
但是,程序员写的是main函数,于是出现了” unresolved external symbol”, 或者无法解析的外部符号 _WinMain@16,该符号在函数 ___tmainCRTStartup 中被引用。
如何修改?只需修改链接器子系统的开关:
main作为入口点函数的则选择:
控制台(/SUBSYSTEM:CONSOLE),
_tWinMain作为入口点函数则选择:
WINDOWS(/SUBSYSTEM:WINDOWS)。
更通用的方法是:把该开关选择为未设置,则链接器会根据入口点函数类型,选择正确的启动函数。
我会继续在论坛上发表我所学的知识,希望能给大家带来帮助,谢谢。/*转载请注明出自 听风独奏 www.GbcDbj.com */