【问题标题】:Removing console window for Glut/FreeGlut/GLFW?删除 Glut/FreeGlut/GLFW 的控制台窗口?
【发布时间】:2011-08-25 02:58:36
【问题描述】:

在 Visual C++ 下,我玩过 Glut/FreeGlut/GLFW。似乎这些项目中的每个人都默认添加了一个 CMD 窗口。我尝试将其删除:

属性->C/C++->预处理器->预处理器 定义

从这里,我删除 _CONSOLE 并用 _WINDOWS 替换它

然后我就下去了:

属性->链接器->系统->子系统

我将选项设置为 Windows (/SUBSYSTEM:WINDOWS)

然后当我尝试在 GLFW 下编译时,出现以下构建错误:

  • 错误 1 ​​错误 LNK2001:未解决 外部符号_WinMain@16 MSVCRT.lib

  • 错误 2 致命错误 LNK1120: 1 未解决的外部glfwWindow.exe

是否可以移除控制台窗口?

【问题讨论】:

    标签: c++ configuration glut freeglut glfw


    【解决方案1】:

    在链接器选项下,将您的入口点设置为 ma​​inCRTStartup 。该函数对 MS libc 进行必要的设置,然后调用 main。

    【讨论】:

    • 结合@Emre 的回答就像一个魅力。谢谢。
    • 严重代码描述项目文件行抑制状态错误LNK2019未解析的外部符号_main在函数“int __cdecl invoke_main(void)”中引用(?invoke_main@@YAHXZ)
    【解决方案2】:

    我的项目只有一个main,(没有WinMain)并且要禁用控制台,我只需将 Linker->System->SubSystem 设置为“Windows (/SUBSYSTEM:WINDOWS)”而不是“Console (/SUBSYSTEM:CONSOLE)”,然后控制台就会运行离开。

    您无需弄乱预处理器定义即可删除控制台窗口。

    我知道我的答案晚了几年,但我希望它有所帮助。

    【讨论】:

    • 我试过这个,但是在VS2015中它给出了一个链接器错误:函数“int __cdecl invoke_main(void)”中引用的未解析的外部符号WinMain
    【解决方案3】:

    大多数链接器都支持自动删除控制台启动代码的选项。

    我认为在 GCC 上它被称为 -mwindows

    【讨论】:

    • +1 因为我有 WinMain,但控制台一直打开。
    【解决方案4】:

    非控制台 Windows 应用程序使用 WinMain() 入口点约定。您的 Glut 示例可能使用标准 C main() 约定。

    如果您只想快速修复演示应用程序,WinAPI 函数FreeConsole() 可能会有所帮助。

    MSDN:http://msdn.microsoft.com/en-us/library/ms683150(v=vs.85).aspx

    【讨论】:

    • 这行得通,我肯定会记录下来,但如果有一个 x 平台的方式来做这件事会很好。再次感谢!
    • 好吧,你在其他平台上并没有真正遇到同样的问题,所以我建议将 FreeConsole() 包装在 #ifdef WIN32 / #endif 块中。
    • 你是说Linux和Mac默认没有控制台窗口?
    • 我不了解 Mac。在 Linux 上,如果您从例如 Ubuntu 桌面启动应用程序,控制台窗口将不会弹出以显示标准输出。程序输出将消失得无影无踪。如果您在终端中运行它,那么它将像往常一样在那里转储标准输出。 FreeConsole() 没有 Linux 等效项。
    • 感谢您告诉我。我将按照 Sean Edwards 在评论中所写的操作并添加#ifdef WIN32。应该这样做。
    【解决方案5】:

    要使用 cmake 摆脱控制台,链接标志可以设置如下:

    set_target_properties(exe_name PROPERTIES 
        LINK_FLAGS "/ENTRY:mainCRTStartup /SUBSYSTEM:WINDOWS")
    

    【讨论】:

    • 这是一个很好的封装到 IF (WIN32) 中以使应用程序跨平台。
    【解决方案6】:

    您需要编写一个WinMain 入口点并复制您现有的代码(来自main):

    int CALLBACK WinMain(
      __in  HINSTANCE hInstance,
      __in  HINSTANCE hPrevInstance,
      __in  LPSTR lpCmdLine,
      __in  int nCmdShow
    ){
        // ...
    }
    

    【讨论】:

    • 好的,我明白你的意思,但我需要一个跨平台的方法来做这件事。我可能不得不接受 onteria_ 所说的话。我会试一试。不过,感谢您的出色回答。
    • 我曾经有一个 WinMain 到主转换器。这样,您的应用程序提供了两个入口点。您只需要将命令行从lpCmdLine 转换为argcargv
    • 我不太清楚你的意思。是我必须为函数提供的东西,还是 Visual Studio 的标志?
    【解决方案7】:

    如果您将新项目创建为控制台应用程序,它将始终这样运行。如果要在实际窗口中运行它,则必须创建一个新的 GUI 项目,否则将不会包含正确的头文件和库。

    所需的 WinMain 函数也会包含在生成的模板文件中。

    【讨论】:

      【解决方案8】:

      当我遇到类似的错误时,我可以通过在 linkerAdvance 部分、选项 Entry Point 中输入以下文本来修复它 以下内容:

      主要

      【讨论】:

      • 这确实解决了错误警告,但没有崩溃并把我带到 atonexit.c
      • 我很惊讶它完全有效。 AFAIK 该设置仅指入口点方法的名称,但根本不会更改签名。您基本上将 ()(HINSTANCE, HINSTANCE, LPSTR, int) 调用为 ()(char**, int),当该方法返回时,这几乎肯定会与您的调用堆栈发生冲突。
      猜你喜欢
      • 2023-03-26
      • 2022-08-22
      • 1970-01-01
      • 1970-01-01
      • 2011-03-29
      • 2016-05-09
      • 1970-01-01
      • 1970-01-01
      • 2011-09-08
      相关资源
      最近更新 更多