繁体   English   中英

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

[英]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运行时。

安装程序可供下载:


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

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

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

如果您想要在发布模式下进行黑客攻击并希望获得两全其美(即小型可执行文件 C运行时):

  1. 下载并安装Windows驱动程序工具包

  2. 在项目属性中,选择发布和:

    • 将以下内容添加到C / C ++ - >常规 - >包含目录:

      • 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 ++ - >代码生成 - >运行时库设置为Multi-threaded DLL (/MD)

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

      • C:\\WinDDK\\7600.16385.1\\lib\\Crt\\i386
      • C:\\WinDDK\\7600.16385.1\\lib\\wxp\\i386 (使用wnet而不是64位的wxp
      • C:\\WinDDK\\7600.16385.1\\lib\\ATL\\i386
      • C:\\WinDDK\\7600.16385.1\\lib\\Mfc\\i386
    • 在Linker - > Input - > Additional Dependencies下添加BufferOverflowU.libmsvcrt_winxp.obj

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

  3. 重建。

  4. ...

  5. 利润。*

*当人们使用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中)并使用它。

此设置可能有所帮助:

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

我想你想要多线程静态链接: / MTd

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM