Компиляция кода в Visual Studio, не требующая установки .net C ++ - PullRequest
4 голосов
/ 25 ноября 2011

Я пытаюсь скомпилировать приложение на C ++, которое работает без необходимости устанавливать .NET Framework или Visual Studio. Я провел некоторое исследование и нашел эту статью из MSDN, показывающую, как скомпилировать собственный код C ++. Однако когда я последовал этому примеру, после запуска сгенерированного исполняемого файла на компьютере без времени выполнения Visual Studio, я получил ошибку MSVCP100D.dll отсутствует на вашем компьютере. Я знаю, что с GCC можно исправить аналогичную ошибку, набрав -static-libgcc -static-libstdc++ для создания статического двоичного файла. Возможно ли это сделать с помощью Visual Studio 2010? Причина, по которой я хочу это сделать, заключается в том, что мне нравится работать с Visual Studio IDE, но я бы хотел, чтобы мой код был переносимым на другие ОС, такие как UNIX. Спасибо!

Примечание: я подумал, что может быть полезно опубликовать код, который я компилирую, для целей тестирования.

#include <iostream>
int main()
{
std::cout << "Hello world";
}

Ответы [ 3 ]

6 голосов
/ 25 ноября 2011

MSVCP100D.dll является отладочной версией MSVCP100.dll.Это библиотеки динамических ссылок, которые реализуют библиотеки времени выполнения C.Это необходимо для реализации стандартных библиотек C ++ в Visual C ++ 2010.

Компилятор связывается с MSVCP100D.dll в режиме отладки.При установке компиляторов, поставляемых с Visual Studio 2010, на компьютере разработчика должно быть MSVCP100D.dll. Если это не так, то при установке что-то пошло не так.

Компилятор ссылается на MSVCP100.dllв режиме релиза.Если вы планируете развернуть свое приложение, вам нужно скомпилировать его в режиме выпуска и распространять версии выпуска двоичного файла.Не распространяйте отладочные версии двоичного файла.

Если даже после этого вы по-прежнему получаете ошибки, вам может потребоваться установить среды выполнения Visual C ++ 2010.

Установщики могут загрузить:


Если вы предпочитаете не связываться с динамической библиотекой, вы можете статически связать библиотеки времени выполнения C с вашим приложением, указав /MT переключатель компилятора какздесь описано .

Обратите внимание, что статическое связывание увеличит размер двоичного файла приложения, и если обновляются библиотеки времени выполнения C (например, улучшения безопасности / производительности), приложение не будет использовать их, если выперекомпилируйте приложение.

Я настоятельно рекомендую вам установить распространяемый пакет в любом случае, так как многие другие приложения вы можете использоватьему нужны библиотеки.

3 голосов
/ 25 ноября 2011

Если вам хочется взломать и вы хотите получить лучшее из обоих миров (например, небольшой исполняемый файл и среда выполнения C) только в режиме выпуска :

  1. Загрузите и установите комплект драйверов Windows .

  2. В свойствах своего проекта выберите Release и:

    • Добавьте следующее в 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).

    • Добавьте следующее в Linker -> General -> Additional Library Directory (выберите соответствующую архитектуру / версию):

      • C:\WinDDK\7600.16385.1\lib\Crt\i386
      • C:\WinDDK\7600.16385.1\lib\wxp\i386 (используйте * 1049)* вместо wxp для 64-разрядных)
      • C:\WinDDK\7600.16385.1\lib\ATL\i386
      • C:\WinDDK\7600.16385.1\lib\Mfc\i386
    • Добавить BufferOverflowU.lib и msvcrt_winxp.obj под Linker -> Input -> Additional Dependencies.

    • Возможно, вам придется отключитьвозможность проверки переполнения буфера (/GS-)

  3. Перестроить.

  4. ...

  5. Прибыль. *

* Уток и прикрытие, когда люди кричат ​​на вас за использование WDK для создания приложений.: P


Примечание:

Если вы используете обработку исключений C ++, у вас возникнут проблемы.

Вы получите неразрешенную ссылку на __CxxFrameHandler3, поскольку msvcrt экспортирует только __CxxFrameHandler, который использует другую версию обработчиков фреймов, чем VS 2008.

Оказывается, у Microsoft уже есть хак для этого в WDK (msvcrt_winxp.obj),но он немного раздутый, поэтому я просто (просто) сделал вместо этого урезанную версию (это заняло days ).

Короче говоря, вы можете исправить это, включив этуфайл сборки в вашем проекте (обязательно укажите _WIN64 для 64-битной версии - пользовательский шаг сборки ниже сделает это за вас):

; 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 или что-то еще, просто найдите версию alloca16.asm в вашем ЭЛТ (плечодолжен быть в CRT Visual Studio) и использовать это.

2 голосов
/ 25 ноября 2011

Этот параметр может помочь:

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

Я думаю, вам нужна многопоточная статическая ссылка: / MTd

...