문제
기본 Windows 응용 프로그램을 개발하고 배포 할 때는 종종 바이너리를 실행하기 전에 런타임을 설치하거나 라이브러리를 이진과 정적으로 연결해야합니다. 예를 들어 Visual Studio 2008을 사용하여 "Win32 콘솔"프로젝트를 구축 한 후 새로운 Windows 7 이미지에서 프로그램을 실행하려고 시도합니다.
나란히 구성된 구성이 잘못 되었기 때문에 응용 프로그램이 시작되지 않았습니다. 자세한 내용은 응용 프로그램 이벤트 로그를 참조하거나 명령 줄 sxstrace.exe 도구를 사용하십시오.
이와 같은 문제가 제기되었습니다 다른 게시물 stackoverflow에서.
응용 프로그램을 어떻게 개발합니까? ~하지 않다 대상 OS에 아직없는 런타임이 필요합니다 (즉, 재배포 가능한 패키지 또는 개인/공유 조립품을 설치할 필요가 없습니까? msvc [mpr] 90.dll을 사용하지 않고 windows system32*. {dll, sys}에서 Windows API를 사용하는 방법은 무엇입니까?
나는 Demoscene에서 나오는 코드의 선을 따라 생각하고 있지만, 그것은 종종 사용할 수 없습니다.
해결책
다른 사람들은 이미 CRT를 정적으로 연결하는 것과 관련하여 응답했습니다. 또한 작은 바이너리를 동시에 원한다면 최선의 방법은 CRT를 완전히 포기하고 가능한 한 Win32 API 기능 만 사용하는 것입니다. 여전히 일부 CRT 코드, 특히 시작과 관련된 CRT 코드를 얻을 수 있습니다 (즉, main
) 및 종료 (atexit
처리 등), 그렇지 않으면 링커는 사용하지 않는 CRT 기능을 연결하지 않습니다.
사용하여 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