项目添加UNICODE支持时,出现链接错误error LNK2019: 无法解析的外部符号 _WinMain

在成功运行的MFC程序添加UNICODE支持时,编译时出现了链接错误:

>msvcrtd.lib(crtexew.obj) : error LNK2019: 无法解析的外部符号 _WinMain@16,该符号在函数 ___tmainCRTStartup 中被引用
1>..\Demo.exe : fatal error LNK1120: 1 个无法解析的外部命令


首先介绍下mainCRTStartup,该函数为C运行时库程序入口函数

以下为MSDN解释,这里就不做翻译了。

The /ENTRY option specifies an entry point function as the starting address for an .exe file or DLL.

The function must be defined with the __stdcall calling convention. The parameters and return value must be defined as documented in the Win32 API for WinMain (for an .exe file) or DllEntryPoint (for a DLL). It is recommended that you let the linker set the entry point so that the C run-time library is initialized correctly, and C++ constructors for static objects are executed.

By default, the starting address is a function name from the C run-time library. The linker selects it according to the attributes of the program, as shown in the following table.

Function name Default for

mainCRTStartup (orwmainCRTStartup)

An application using /SUBSYSTEM:CONSOLE; calls main (or wmain)

WinMainCRTStartup (orwWinMainCRTStartup)

An application using /SUBSYSTEM:WINDOWS; calls WinMain (or wWinMain), which must be defined with __stdcall

_DllMainCRTStartup

A DLL; calls DllMain, which must be defined with __stdcall, if it exists

If the /DLL or /SUBSYSTEM option is not specified, the linker selects a subsystem and entry point depending on whether main or WinMain is defined.

The functions mainWinMain, and DllMain are the three forms of the user-defined entry point.

When creating a managed image, the function specified with /ENTRY must have a signature of (LPVOID var1, DWORD var2, LPVOID var3).

For information on how to define your own DllMain entry point, see Run-Time Library Behavior .

To set this linker option in the Visual Studio development environment

  1. Open the project's Property Pages dialog box. For details, see Setting Visual C++ Project Properties.

  2. Click the Linker folder.

  3. Click the Advanced property page.

  4. Modify the Entry Point property.

从上面可以看出,console程序、GUI程序和DLL所使用的C运行时库入口函数均不同

以下为网上找到的解释,里面说明了UNICODE程序的mainCRTStartup入口函数

Where does your console program start? Did I hear you say main? If you did, you said what I would have said before journeying into the inner Stationworkings of the C Runtime.

Windows isn't nice enough to provide your app with a ready-made argc and argv. All it does is call a void function() specified in the EXE header. And by default, that function is called mainCRTStartup. Here is a simple example:

extern "C" void __cdecl mainCRTStartup()
{
    int argc = _init_args();
    _init_atexit();
    _initterm(__xc_a, __xc_z);         // Call C++ constructors

    int ret = main(argc, _argv, 0);    // Don't handle environment strings

    _doexit();
    ExitProcess(ret);
}

We start by creating argc and argv, which we later pass to main. But before we do that we have to take care of some things, like calling the constructors for static C++ objects.

The same thing happens in GUI programs, except the function is called WinMainCRTStartup. And for DLLs, the true entry point is _DllMainCRTStartup. Unicode programs look for wmainCRTStartup and wWinMainCRTStartuprespectively. DllMain appears to stay the same.

从上述解释中,可以知道UNICODE程序使用w开头的mainCRTStartup,之所以以‘w’开头,与wchar类似


这里,我们就知道上述错误的原因了,是选错了入口函数,对于我所写的UNICODE GUI程序应该使用wWinMainCRTStartup入口函数。上述MSDN中有提到如何更改入口函数,更改如下


重新编译,成功通过

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值