【问题标题】:How can I make a win32 app with no dependency on the msvc dll?如何制作不依赖 msvc dll 的 win32 应用程序?
【发布时间】:2017-01-28 19:38:48
【问题描述】:

我想使用 Visual Studio 编写一个不依赖 msvc dll 的 c++ win32 应用程序。

我尝试了/NODEFAULTLIB 选项,但之后我得到一个未解决的外部错误,即使是“空”程序,因为没有库。我该如何纠正?我有要链接哪些库?

这是我尝试使用/NODEFAULTLIB 选项编译但失败的简单代码。

#include <Windows.h>

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow) {

}

【问题讨论】:

  • 您可能在 IDE 中创建了错误的项目类型。您创建的项目类型是什么?
  • @NeilButterworth 我在 c++ 标签下创建了 Win32/Empty Win32 项目。
  • @RawN 这不仅仅是关于今天每个人至少有几 TB 的磁盘大小,而且为​​什么我不能这样做?
  • 这样做只会让自己度过一段非常糟糕的时光。编译器生成 CRT 作用的代码和数据。这包括初始化和销毁​​全局对象、处理异常等。所有这些未解决的链接器错误都是您需要自己或在另一个库中提供的功能的一部分。由于您要替换的大多数内部结构都没有记录,因此您将很难同时进行这两项操作。
  • @SüleymanKenar - 是的,我在这方面拥有丰富的知识和丰富的经验。但是这对你来说是为了什么?从您的程序入口点WinMain 开始 - 谁必须调用它?!如果您不想使用CRT - 您的条目必须是void somefunc() 并且需要将somefunc 设置为exe 入口点。然后很多取决于您的 c++ 编译器选项(例如运行时检查等)以及您在代码中使用的功能。你准备好使用ntdllp.lib 作为运行时(比如异常处理程序)吗?你需要有足够的知识和理由这样做

标签: c++ visual-studio winapi


【解决方案1】:
#undef UNICODE
#define UNICODE
#include <windows.h>

void startup()
{
    MessageBox( 0, L"Click the OK button, please.", L"Hi!", MB_SETFOREGROUND );
    ExitProcess( 0 );
}
[C:\我的\论坛\so\279] > cl minimum.cpp /link /nodefaultlib /entry:startup /subsystem:console kernel32.lib user32.lib 最小的.cpp [C:\我的\论坛\so\279] > 目录 驱动器 C 中的卷是操作系统 卷序列号为 58BC-07CA C:\my\forums\so\279 目录 2017 年 1 月 28 日 21:43 。 2017 年 1 月 28 日 21:43 .. 28.01.2017 21:43 215 minimum.cpp 28.01.2017 21:43 2 560 minimum.exe 28.01.2017 21:43 860 minimum.obj 3 个文件 3 635 字节 2 Dir(s) 274 278 531 072 字节空闲 [C:\我的\论坛\so\279] > _

cl 是 Visual C++ 编译器。我的默认选项(通过CL 环境变量)是/nologo /EHsc /GR /W4 /FI "iso646.h",但我相信只有异常处理选项会影响这里的任何内容,如果这一切都是如此。 user32.lib 库已链接,因为我使用了 MessageBox 函数。


请注意,运行时库负责处理部分 C++ 核心语言基础结构。这包括命名空间范围变量的动态初始化,并且根据编译器的不同,它可能包括一些对异常的支持。我不知道 Visual C++ 在这方面的详细信息,但有必要非常非常小心:在工具的基本假设不成立的情况下运行。

【讨论】:

  • 您可能还需要/DYNAMICBASE:NO 和/FIXED:YES 才能使小程序可靠地运行,尽管我认为这个问题only affects 64-bit applications。另一个附带条件是,您的任何函数都不能有超过一页的局部变量。
  • @HarryJohnston:我不确定我是否同意你的第一点。关于与局部变量分配有关的页面大小的最后一个对我来说是新闻。你有参考吗?
  • 无参考。我只知道,如果您在局部变量上使用过多的堆栈空间,则构建会失败,并且缺少一个名为 __chkstk IIRC 的函数? (这只是一个有根据的猜测,限制是一页,但我认为一个很好;缺少函数的原因与分配给堆栈的虚拟内存的处理方式有关,虚拟内存是按页分配的.) 至于需要禁用非常小的可执行文件的重定位,这是另一个实际观察结果,尽管可以想象微软已经修复了有问题的错误。
  • 运行时库还有其他不可见的依赖关系。例如,用于多字算术、GS 检查、purecall 存根、RTTI、异常、try/catch、__try/__except、magic statics、atexit、_initterm 的辅助函数...
  • @IInspectable - RTTI - 我根本不使用,这不是强制性的。 magic statics - 你的意思是 _Init_thread_header, _Init_thread_footer 函数和 _Init_thread_epoch var ?我在需要时自己实现它
猜你喜欢
  • 2014-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-29
  • 2010-11-19
  • 1970-01-01
相关资源
最近更新 更多