在Visual Studio中编译不需要C++安装.net的代码
Compiling code in Visual Studio that does not require .net to be installed C++
我正在尝试用C++编译一个无需安装.net框架或Visual Studio 运行时即可工作的应用程序。我做了一些研究,发现MSDN的这篇文章展示了如何编译本机C++代码。但是,当我按照此示例进行操作时,在没有Visual Studio运行时的计算机上运行生成的可执行文件后,我收到一个错误MSVCP100D.dll
您的计算机中缺少该错误。我知道可以通过键入 -static-libgcc -static-libstdc++
来生成静态二进制文件来修复 GCC 的类似错误。是否可以使用 Visual Studio 2010 执行此操作?我希望这样做的原因是我喜欢使用Visual Studio IDE,但我希望我的代码可以移植到其他操作系统,如UNIX。谢谢!
注意:我认为发布我正在编译的代码以进行测试可能会有所帮助。
#include <iostream>
int main()
{
std::cout << "Hello world";
}
MSVCP100D.dll
是MSVCP100.dll
的调试版本。它们是实现 C 运行时库的动态链接库。这是在 Visual C++ 2010 中实现C++标准库所必需的。
编译器在调试模式下链接到MSVCP100D.dll
。安装 Visual Studio 2010 附带的编译器时,开发计算机上应该有一个MSVCP100D.dll
。如果不是这样,则安装出了问题。
编译器在发布模式下链接到MSVCP100.dll
。如果计划部署应用程序,则需要在发布模式下编译并分发二进制文件的发布版本。不要分发二进制文件的调试版本。
如果即使这样做了,您仍然收到错误,您可能需要安装 Visual C++ 2010 运行时。
安装程序可供下载:
- Microsoft Visual C++ 2010 SP1 可再发行组件程序包 (x86(
- Microsoft Visual C++ 2010 SP1 可再发行组件程序包 (x64(
如果不链接到动态库,可以通过指定 /MT
编译器开关将 C 运行时库静态链接到应用程序中,如此处所述。
请注意,静态链接将增加应用程序二进制文件的大小,如果更新了 C 运行时库(例如安全性/性能改进(,除非您重新编译应用程序,否则应用程序将不会使用它们。
我强烈建议您无论如何都要安装可再发行组件包,因为您可能使用的许多其他应用程序可能需要这些库。
处游荡并希望仅在发布模式下两全其美(即小型可执行文件和 C 运行时(:
下载并安装 Windows 驱动程序工具包。
在项目"属性"中,选择"发布",然后:
将以下内容添加到 C/C++ -> 常规 -> 包含目录:
-
C:WinDDK7600.16385.1inccrt
-
C:WinDDK7600.16385.1incapi
-
C:WinDDK7600.16385.1incatl71
-
C:WinDDK7600.16385.1incmfc42
-
将 C/C++ -> 代码生成 -> 运行时库设置为
Multi-threaded DLL (/MD)
。将以下内容添加到链接器 -> 常规 -> 其他库目录(根据需要选择体系结构/版本(:
-
C:WinDDK7600.16385.1libCrti386
-
C:WinDDK7600.16385.1libwxpi386
(对于 64 位,使用wnet
而不是wxp
( -
C:WinDDK7600.16385.1libATLi386
-
C:WinDDK7600.16385.1libMfci386
-
在链接器->输入->其他依赖项下添加
BufferOverflowU.lib
和msvcrt_winxp.obj
。您可能需要禁用缓冲区溢出检查 (
/GS-
(
重建。
。
利润。*
* 当人们因为使用 WDK 构建应用程序而对你大喊大叫时,躲避和掩护。 :P
注意:
如果使用C++异常处理,则会遇到麻烦。
你会得到一个对__CxxFrameHandler3
的未解析引用,因为msvcrt
只导出__CxxFrameHandler
,它使用与VS 2008不同的帧处理程序版本。
事实证明,Microsoft已经在WDK(msvcrt_winxp.obj
(中对此进行了黑客攻击,但它有点臃肿,所以我只是("只是"(制作了一个精简版本(花了几天时间(。
长话短说,您可以通过在项目中包含此程序集文件来修复它(确保为 64 位定义_WIN64
- 下面的自定义构建步骤会为您执行此操作(:
; Custom build step (use for x64 only):
; ml64.exe /Fo"$(IntDir)$(InputName).obj" /D_WIN64 /c /nologo /W3 /Zi /Ta "$(InputPath)"
; Custom build output: $(IntDir)$(InputName).obj
;
; Relevant links:
; http://kobyk.wordpress.com/2007/07/20/dynamically-linking-with-msvcrtdll-using-visual-c-2005/
; http://www.openrce.org/articles/full_view/21
; http://blogs.msdn.com/b/freik/archive/2006/01/04/509372.aspx
ifndef _WIN64
.386
.model flat, c
endif
option dotname
extern __CxxFrameHandler: PROC
ifdef _WIN64
extern __imp___CxxFrameHandler: PROC
extern __imp_VirtualProtect: PROC
extern __imp_Sleep: PROC
extern __imp_GetVersion: PROC
endif
.data
ifdef _WIN64
;ProtectFlag EQU ?ProtectFlag@?1??__CxxFrameHandler3@@9@9
ProtectFlag dd ?
endif
ifdef _WIN64
endif
.code
ifdef _WIN64
includelib kernel32.lib
endif
includelib msvcrt.lib
public __CxxFrameHandler3
ifdef _WIN64
__CxxFrameHandler3 proc frame
else
__CxxFrameHandler3 proc
endif
ifndef _WIN64
push ebp
mov ebp,esp
sub esp,28h
push ebx
push esi
push edi
cld
mov dword ptr [ebp-4],eax
mov esi,dword ptr [ebp-4]
push 9
pop ecx
lea edi,[ebp-28h]
rep movs dword ptr es:[edi],dword ptr [esi]
mov eax,dword ptr [ebp-28h]
and eax,0F9930520h
or eax,019930520h
mov dword ptr [ebp-28h],eax
lea eax,[ebp-28h]
mov dword ptr [ebp-4],eax
push dword ptr [ebp+14h]
push dword ptr [ebp+10h]
push dword ptr [ebp+0Ch]
push dword ptr [ebp+8]
mov eax,dword ptr [ebp-4]
call __CxxFrameHandler
add esp,10h
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
else
mov rax,rsp
mov qword ptr [rax+8],rbx
.savereg rbx, 50h
mov qword ptr [rax+10h],rbp
.savereg rbp, 58h
mov qword ptr [rax+18h],rsi
.savereg rsi, 60h
push rdi
.pushreg rdi
push r12
.pushreg r12
push r13
.pushreg r13
sub rsp,30h
.allocstack 30h
.endprolog
mov dword ptr [rax+20h],40h
mov rax,qword ptr [r9+38h]
mov rdi,r9
mov ebx,dword ptr [rax]
mov rsi,r8
mov rbp,rdx
add rbx,qword ptr [r9+8]
mov r12,rcx
mov eax,dword ptr [rbx]
and eax,1FFFFFFFh
cmp eax,19930520h
je L140001261
mov r13d,1
mov eax,r13d
lock xadd dword ptr [ProtectFlag],eax
add eax,r13d
cmp eax,r13d
je L140001217
L1400011F0:
lock add dword ptr [ProtectFlag],0FFFFFFFFh
mov ecx,0Ah
call qword ptr [__imp_Sleep]
mov r11d,r13d
lock xadd dword ptr [ProtectFlag],r11d
add r11d,r13d
cmp r11d,r13d
jne L1400011F0
L140001217:
mov r8d,dword ptr [rsp+68h]
mov r13d,4
lea r9,[rsp+20h]
mov rdx,r13
mov rcx,rbx
call qword ptr [__imp_VirtualProtect]
test eax,eax
je L140001259
and dword ptr [rbx],0F9930520h
or dword ptr [rbx],19930520h
mov r8d,dword ptr [rsp+20h]
lea r9,[rsp+68h]
mov rdx,r13
mov rcx,rbx
call qword ptr [__imp_VirtualProtect]
L140001259:
lock add dword ptr [ProtectFlag],0FFFFFFFFh
L140001261:
mov r9,rdi
mov r8,rsi
mov rdx,rbp
mov rcx,r12
call qword ptr [__imp___CxxFrameHandler]
mov rbx,qword ptr [rsp+50h]
mov rbp,qword ptr [rsp+58h]
mov rsi,qword ptr [rsp+60h]
add rsp,30h
pop r13
pop r12
pop rdi
ret
endif
__CxxFrameHandler3 endp
end
(注意:你不能在 C 或 C++ 中实现这一点,因为调用约定与 C/C++ 使用的约定不同——它似乎是一种未记录的格式,假设寄存器以某种方式设置。
如果你得到对_chkstk
或_alloca
或其他内容的未解析引用,只需在CRT中找到alloca16.asm
的一个版本(应该在Visual Studio的CRT中(并使用它。
此设置可能会有所帮助:
http://msdn.microsoft.com/en-us/library/abx4dbyh.aspx
我认为你想要多线程静态链接:/MTd
- 在Ubuntu 16.04上安装Cilk时出现问题
- 在CMakeLists.txt的安装功能中使用.cmake文件有什么用
- C++:如何在CLion IDE中安装Boost
- 安装opencv失败-粘贴CMakeError.log的内容
- 在cygwin中测试新的boost安装时出现cpp错误
- 有人安装"IITB Simplecpp in mac"吗?
- 在 C++/CLI 中将 .NET 事件从一个 DLL 引发到另一个 DLL
- 如何在 64 位 vb.net Windows 应用程序中引用 32 位 dll
- 我可以在 Arduino 的库文件夹之外安装库吗?
- Mingw-64 在构建和安装后不会编译 openCV 代码
- 为什么构建目录中新构建的共享库与安装目录中的副本具有不同的依赖项集?
- 安装 libc++ 时出现问题
- 安装MinGW后C++编译器不起作用?
- 加载与引用 .NET DLL 位于同一文件夹中的引用的 .NET DLL 时"Not found"异常
- 介子复制/安装头文件到输出目录并保持文件夹结构
- 无法安装 R 包 "nloptr"(Ubuntu 16.04 上的 R3.6.2) - C++编译器问题
- 无法安装RNNLIB(http://sourceforge.net/p/rnnl/wiki/Home/)在Mac OSX
- 如何在没有[DefaultInstall]部分的情况下从.NET桌面应用程序安装INF驱动程序
- 在Visual Studio中编译不需要C++安装.net的代码
- .net应用程序的引导程序(预安装程序)