在Visual Studio中编译不需要.net安装C ++的代码

时间:2011-11-25 04:31:15

标签: .net c++ visual-studio-2010 static runtime

我正在尝试使用C ++编译应用程序,该应用程序在没有.net框架或必须安装Visual Studio运行时的情况下工作。我做了一些研究,发现MSDN中的this article显示了如何编译本机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";
}

3 个答案:

答案 0 :(得分:6)

MSVCP100D.dllMSVCP100.dll的调试版本。它们是实现C运行时库的动态链接库。这是在Visual C ++ 2010中实现C ++标准库所必需的。

编译器在调试模式下链接MSVCP100D.dll。当您安装Visual Studio 2010附带的编译器时,您的开发计算机上应该有MSVCP100D.dll。如果不是这样,那么安装就会出现问题。

编译器在发布模式下链接MSVCP100.dll。如果您计划部署应用程序,则需要在发布模式下进行编译并分发二进制文件的发行版本。不要分发二进制文件的调试版本。

如果即使这样做仍然会出现错误,您可能需要安装Visual C ++ 2010运行时。

可以下载安装程序:


如果您不想链接动态库,可以通过指定/MT编译器开关as described here将C运行时库静态链接到应用程序中。

请注意,静态链接会增加应用程序二进制文件的大小,如果更新了C运行时库(例如安全性/性能改进),除非重新编译应用程序,否则应用程序将不会使用它们。

我强烈建议您安装可再发行软件包,因为您可能使用的许多其他应用程序可能需要这些库。

答案 1 :(得分:3)

如果你想在发布模式中想要充分利用这两个世界(即小型可执行文件 C运行时),那么:

  1. 下载并安装Windows Driver Kit

  2. 在项目属性中,选择下达并:

    • 将以下内容添加到C / C ++中 - &gt;一般 - &gt;包括目录:

      • C:\WinDDK\7600.16385.1\inc\crt
      • C:\WinDDK\7600.16385.1\inc\api
      • C:\WinDDK\7600.16385.1\inc\atl71
      • C:\WinDDK\7600.16385.1\inc\mfc42
    • 设置C / C ++ - &gt;代码生成 - &gt;运行时库到Multi-threaded DLL (/MD)

    • 将以下内容添加到链接器 - &gt;一般 - &gt;其他库目录(根据需要选择体系结构/版本):

      • C:\WinDDK\7600.16385.1\lib\Crt\i386
      • C:\WinDDK\7600.16385.1\lib\wxp\i386(使用wnet代替wxp代表64位)
      • C:\WinDDK\7600.16385.1\lib\ATL\i386
      • C:\WinDDK\7600.16385.1\lib\Mfc\i386
    • 在链接器下添加BufferOverflowU.libmsvcrt_winxp.obj - &gt;输入 - &gt;附加依赖。

    • 您可能需要禁用缓冲区溢出检查(/GS-

  3. 重建。

  4. ...

  5. 利润。*

  6. *当人们使用WDK构建应用程序时,人们会大吼大叫。 :P


    注意:

    如果使用C ++异常处理,则会遇到麻烦。

    您将获得对__CxxFrameHandler3的未解析引用,因为msvcrt仅导出__CxxFrameHandler,它使用与VS 2008不同版本的帧处理程序。

    事实证明微软已经在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中)并使用它。

答案 2 :(得分:2)

此设置可能会有所帮助:

http://msdn.microsoft.com/en-us/library/abx4dbyh.aspx

我认为您需要多线程静态链接: / MTd