在开发和部署本机Windows应用程序时,我经常需要安装运行时,然后才能运行我的二进制文件,或者将库与二进制文件静态链接。例如,在使用Visual Studio 2008构建“ Win32控制台”项目之后,试图在Fresh Windows 7图像上运行该程序的结果:

该应用程序未能启动,因为其并排配置不正确。请参阅“应用程序”日志或使用命令行sxstrace.exe工具以获取更多详细信息。

这样的问题已经提出 其他帖子 在stackoverflow上。

一个人如何开发应用程序 需要尚未在目标操作系统上的运行时间(即不需要安装可重新分布的软件包或私人/并排组件)?如何避免使用msvc [mpr] 90.dll,只使用 Windows System32*。{dll,sys}中的Windows API?

我正在考虑符合法型法规的代码线条,但这常常无法提供。

有帮助吗?

解决方案

其他人已经在静态链接CRT方面做出了反应。如果您还希望同时使用一个小二进制文件,那么您最好的选择就是完全放弃CRT,并且仅使用Win32 API功能。您仍然会获得一些CRT代码,最著名的是与启动有关(即调用的 main)和关闭(atexit 处理等),但是否则,链接器不会链接您不使用的CRT函数。

您可以通过使用 /Zl 编译器开关。这意味着 main 但是,将不再起作用 - 您需要定义 WinMain (名称没关系,但是签名必须匹配,并且必须是 __stdcall),您必须指定您的名称 WinMain- 像链接器的入口点一样函数 /entry: 转变。这将节省您〜30kb的CRT代码(在.cpp上测试了一个空的 main).

如果您走后一条路线,您可能还必须处理编译器内在问题。有些功能名义上由CRT定义(并在其标题中声明),但由编译器专门处理,以便在可能的情况下插入呼叫点的优化汇编指令 - 示例是示例 memset, strlen, ,以及大量功能 <math.h>;可以找到完整的列表 这里. 。由于您没有CRT,如果您需要这些功能,或者可以避免它,但由于性能的提高而更喜欢固有的(难以做得比 memset, ,例如),然后您必须自己声明它们,并使用 #pragma intrinsic. 。例如:

// Contains macros and typedef only, so safe to include without CRT.
// We need it here for size_t.
#include <stddef.h> 

extern "C"
{
    int abs(int);
    void* memset(void*, int, size_t); 
}

#pragma intrinsic(abs, memset)

int __stdcall main(void*, void*, char*, int)
{
    char tmp[10];
    memset(tmp, abs(-123), 10);
    return 0;
}

以上可以与:

cl /c /Zl foo.cpp
link /entry:main foo.obj

其他提示

通过静态链接CRT /MT 切换(如果您使用的话,同样是MFC)。

静态链接限制了您可以在某种程度上使用DLL的操作,但是对于简单的可执行文件,它像魅力一样工作。 (如果您要运送DLL,则可以随时运送私人集会。)

使用静态CRT。这不会创建对MSVC*.dll的依赖性。 CRT直接链接到您的程序中。这不会造成依赖性,但确实会增加可执行文件的大小。

有关不同CRT选项的更多信息 这里.

静态链接运行时。 MS Visual C ++具有该选项 /MT(默认为 /MD)

我认为这样做的一种方法是不使用Visual Studio,而是依靠命令行SDK工具。 (您也可以弄清楚如何配置如何做自己想做的事情,但这似乎更难。)例如:

cl /c app.cpp
link app.obj ws2_32.lib
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top