V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
llllllllllll
V2EX  ›  Windows

一段很简单的代码,换 VS2017 就编译不过去了,想不通

  •  
  •   llllllllllll · 2017-06-07 11:56:17 +08:00 · 6044 次点击
    这是一个创建于 2728 天前的主题,其中的信息可能已经有所发展或是发生改变。
    只是修改了入口点。
    用 VS2005 就可以。
    但是换 2017 就不行。
    编译就报错。
    各位有碰到过这种诡异的现象么。

    #pragma comment(linker,"/entry:main")

    #include <stdio.h>
    #include <string.h>


    void main()
    {
    int n = strlen("ss");
    }
    13 条回复    2017-06-07 21:23:47 +08:00
    yksoft1
        1
    yksoft1  
       2017-06-07 12:37:23 +08:00
    估计是高版本的 CL 不支持这种 pragma 了。改入口最好还是直接在链接器命令行( makefile 里)指定参数,或者用 def 文件
    wevsty
        2
    wevsty  
       2017-06-07 12:52:51 +08:00
    编译的错误提示是?
    确定是编译错误而不是链接错误?
    我这里测试提示是 LNK2019。
    #pragma comment(linker,"/entry:main")
    手动指定 main 函数为起点,这样做会跳过 CRT 运行库初始化的过程,可能由于 VS 自身的一些机制引起各种奇奇怪怪的问题。
    llllllllllll
        3
    llllllllllll  
    OP
       2017-06-07 13:42:21 +08:00
    @wevsty
    错误的确是 2019
    有什么办法吗

    已启动生成: 项目: ConsoleApplication3, 配置: Debug Win32 ------
    1>main.obj : error LNK2019: 无法解析的外部符号 _strlen,该符号在函数 _main 中被引用
    1>MSVCRTD.lib(_init_.obj) : error LNK2019: 无法解析的外部符号 __CrtDbgReport,该符号在函数 __CRT_RTC_INIT 中被引用
    1>MSVCRTD.lib(_init_.obj) : error LNK2019: 无法解析的外部符号 __CrtDbgReportW,该符号在函数 __CRT_RTC_INITW 中被引用
    1>MSVCRTD.lib(_error_.obj) : error LNK2019: 无法解析的外部符号 _strcpy_s,该符号在函数 "void __cdecl _RTC_StackFailure(void *,char const *)" (?_RTC_StackFailure@@YAXPAXPBD@Z) 中被引用
    1>MSVCRTD.lib(_error_.obj) : error LNK2019: 无法解析的外部符号 _strcat_s,该符号在函数 "void __cdecl _RTC_StackFailure(void *,char const *)" (?_RTC_StackFailure@@YAXPAXPBD@Z) 中被引用
    1>MSVCRTD.lib(_error_.obj) : error LNK2019: 无法解析的外部符号 ___stdio_common_vsprintf_s,该符号在函数 __vsprintf_s_l 中被引用
    1>MSVCRTD.lib(_pdblkup_.obj) : error LNK2019: 无法解析的外部符号 __wmakepath_s,该符号在函数 "int __cdecl GetPdbDllPathFromFilePath(wchar_t const *,wchar_t *,unsigned int)" (?GetPdbDllPathFromFilePath@@YAHPB_WPA_WI@Z) 中被引用
    1>MSVCRTD.lib(_pdblkup_.obj) : error LNK2019: 无法解析的外部符号 __wsplitpath_s,该符号在函数 "int __cdecl GetPdbDllPathFromFilePath(wchar_t const *,wchar_t *,unsigned int)" (?GetPdbDllPathFromFilePath@@YAHPB_WPA_WI@Z) 中被引用
    1>MSVCRTD.lib(_pdblkup_.obj) : error LNK2019: 无法解析的外部符号 _wcscpy_s,该符号在函数 "int __cdecl GetPdbDllPathFromFilePath(wchar_t const *,wchar_t *,unsigned int)" (?GetPdbDllPathFromFilePath@@YAHPB_WPA_WI@Z) 中被引用
    1>MSVCRTD.lib(_pdblkup_.obj) : error LNK2019: 无法解析的外部符号 ___vcrt_GetModuleFileNameW,该符号在函数 "struct HINSTANCE__ * __cdecl GetPdbDll(void)" (?GetPdbDll@@YAPAUHINSTANCE__@@XZ) 中被引用
    1>MSVCRTD.lib(_pdblkup_.obj) : error LNK2019: 无法解析的外部符号 ___vcrt_GetModuleHandleW,该符号在函数 "struct HINSTANCE__ * __cdecl GetPdbDll(void)" (?GetPdbDll@@YAPAUHINSTANCE__@@XZ) 中被引用
    1>MSVCRTD.lib(_pdblkup_.obj) : error LNK2019: 无法解析的外部符号 ___vcrt_LoadLibraryExW,该符号在函数 "struct HINSTANCE__ * __cdecl GetPdbDll(void)" (?GetPdbDll@@YAPAUHINSTANCE__@@XZ) 中被引用
    1>MSVCRTD.lib(_chandler4gs_.obj) : error LNK2019: 无法解析的外部符号 __except_handler4_common,该符号在函数 __except_handler4 中被引用
    1>D:\CodeSpace\VS2017\TEST\ConsoleApplication3\Debug\ConsoleApplication3.exe : fatal error LNK1120: 13 个无法解析的外部命令
    1>已完成生成项目“ ConsoleApplication3.vcxproj ”的操作 - 失败。
    ========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0 个 ==========
    llllllllllll
        4
    llllllllllll  
    OP
       2017-06-07 13:43:08 +08:00
    @yksoft1
    感谢建议
    nicevar
        5
    nicevar  
       2017-06-07 13:51:26 +08:00
    加上#pragma comment(linker, "/INCLUDE:_mainCRTStartup")就行了
    llllllllllll
        6
    llllllllllll  
    OP
       2017-06-07 14:03:26 +08:00
    @nicevar
    擦,确实!
    为什么,这个是什么原理。
    请赐教!
    fo2w
        7
    fo2w  
       2017-06-07 14:06:29 +08:00
    我猜, 你改成
    #pragma comment(linker,"/entry:_main")
    也可以链接成功
    wevsty
        8
    wevsty  
       2017-06-07 14:19:36 +08:00
    @llllllllllll
    我不明白为什么一定要手动指定 main 函数作为入口。使用默认的 mainCRTStartup 显然是更安全的选项。
    如果一定要这样做可以使用下面的方法手动链接运行库。
    #pragma comment(lib, "msvcrtd.lib")
    #pragma comment(lib, "vcruntimed.lib")
    #pragma comment(lib, "ucrtd.lib")
    需要根据自己的编译选项来确定链接哪些库
    Release DLLs (/MD ): msvcrt.lib vcruntime.lib ucrt.lib
    Debug DLLs (/MDd): msvcrtd.lib vcruntimed.lib ucrtd.lib
    Release Static (/MT ): libcmt.lib libvcruntime.lib libucrt.lib
    Debug Static (/MTd): libcmtd.lib libvcruntimed.lib libucrtd.lib
    llllllllllll
        9
    llllllllllll  
    OP
       2017-06-07 17:36:08 +08:00
    @fo2w
    额,试了一把,不行呀
    llllllllllll
        10
    llllllllllll  
    OP
       2017-06-07 17:39:47 +08:00
    @wevsty
    好厉害,你的方法也成功了。
    其实不是非要怎么样。只是想试一把。
    xz
        11
    xz  
       2017-06-07 20:55:10 +08:00
    莫名其妙的就收到了提醒......
    llllllllllll
        12
    llllllllllll  
    OP
       2017-06-07 21:06:51 +08:00
    @xz
    哈哈,你关注了什么奇怪的关键词~
    isCyan
        13
    isCyan  
       2017-06-07 21:23:47 +08:00 via Android
    @xz
    @llllllllllll
    那一堆报错信息不小心把你艾特了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3583 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 11:11 · PVG 19:11 · LAX 03:11 · JFK 06:11
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.