잠재적인 업그레이드 문제 개요(Visual C++)

지난 몇 년 동안 C++ 언어 자체, C++ 표준 라이브러리, C 런타임(CRT) 및 MFC, ATL 등의 기타 라이브러리의 변경과 함께 Microsoft C++ 컴파일러에도 많은 변화가 있었습니다. 따라서 이전 버전의 Visual Studio에서 애플리케이션을 업그레이드하면 이전에 클린 컴파일된 코드에서 컴파일러 및 링커 오류 및 경고가 표시될 수 있습니다. 원래 코드베이스가 오래될수록 이러한 오류 가능성이 커집니다. 이 개요에서는 볼 수 있는 가장 일반적인 문제 클래스를 요약하고 자세한 정보에 대한 링크를 제공합니다.

참고 항목

과거에는 여러 버전의 Visual Studio에 걸쳐 있는 업그레이드를 한 번에 하나씩 증분 방식으로 수행하는 것이 좋습니다. 이 방법은 더 이상 권장되지 않습니다. 코드 베이스가 얼마나 오래 되었는지에 관계없이 Visual Studio의 최신 버전으로 업그레이드하는 것이 거의 항상 더 간단하다는 것을 알게 되었습니다.

업그레이드 프로세스와 관련된 질문이나 의견이 있으면 vcupgrade@microsoft.com로 보내주시기 바랍니다.

라이브러리 및 도구 집합 종속성

참고 항목

이 섹션은 Visual Studio 2013 및 이전 버전으로 빌드된 애플리케이션 및 라이브러리에 적용됩니다. Visual Studio 2015, Visual Studio 2017 및 Visual Studio 2019에서 사용되는 도구 집합은 이진 호환이 가능합니다. 자세한 내용은 Visual Studio 버전 간의 C++ 이진 호환성을 참조하세요.

Visual Studio 2013 또는 이전 버전에서 최신 버전으로 앱을 업그레이드하는 경우 앱이 연결되는 모든 라이브러리 및 DLL을 업그레이드하는 것이 좋습니다. 소스 코드에 액세스할 수 있어야 하거나 라이브러리 공급업체가 동일한 주 버전의 컴파일러로 컴파일된 새 이진 파일을 제공해야 합니다. 이러한 조건 중 하나에 해당하면 이진 호환성의 세부 사항을 처리하는 이 섹션을 건너뛰어도 됩니다. 둘 다 그렇지 않은 경우 라이브러리가 업그레이드된 앱에서 작동하지 않을 수 있습니다. 이 섹션의 정보는 업그레이드를 계속할 수 있는지 여부를 이해하는 데 도움이 됩니다.

도구 집합

.obj.lib 파일 형식은 잘 정의되며 거의 변경되지 않습니다. 때때로 이러한 파일 형식이 추가되지만, 일반적으로 이러한 추가 항목은 최신 도구 집합이 이전 도구 집합에서 생성된 개체 파일 및 라이브러리를 사용하는 데 영향을 주지 않습니다. 주요 예외는 (전체 프로그램 최적화)를 사용하여 /GL 컴파일하는 경우입니다. 사용하여 /GL컴파일하는 경우 생성에 사용된 것과 동일한 도구 집합을 사용하여 결과 개체 파일만 연결할 수 있습니다. 따라서 Visual Studio 2017(v141) 컴파일러를 /GL 사용하여 개체 파일을 생성하고 사용하는 경우 Visual Studio 2017(v141) 링커를 사용하여 연결해야 합니다. 개체 파일 내의 내부 데이터 구조가 주요 버전의 도구 집합에서 안정적이지 않기 때문입니다. 최신 도구 집합은 이전 데이터 형식을 이해하지 못합니다.

C++에는 안정적인 ABI(애플리케이션 이진 인터페이스)가 없습니다. 그러나 Visual Studio는 릴리스의 모든 부 버전에 대해 안정적인 C++ ABI를 유지 관리합니다. Visual Studio 2015(v140), Visual Studio 2017(v141), Visual Studio 2019(v142) 및 Visual Studio 2022(v143) 도구 집합은 부 버전에만 다릅니다. 모두 동일한 주 버전 번호인 14를 가지고 있습니다. 자세한 내용은 Visual Studio 버전 간의 C++ 이진 호환성을 참조하세요.

C++ 링크와 함게 외부 기호를 포함하는 개체 파일이 있는 경우 해당 개체 파일은 다른 주 버전의 도구 집합에 의해 생성된 개체 파일과 올바르게 연결되지 않을 수 있습니다. 가능한 여러 결과가 있습니다. 링크가 완전히 실패할 수 있습니다(예: 이름 장식이 변경된 경우). 링크는 성공할 수 있지만 런타임에 앱이 실패할 수 있습니다(예: 형식 레이아웃이 변경된 경우). 또는 앱이 계속 작동할 수 있으며 아무 것도 잘못되지 않습니다. 또한 C++ ABI는 안정적이지 않지만 C ABI 및 COM에 필요한 C++ ABI의 하위 집합은 안정적입니다.

가져오기 라이브러리에 링크하면 런타임 시 ABI 호환성을 유지하는 Visual Studio 재배포 가능 라이브러리의 이후 버전을 사용할 수 있습니다. 예를 들어 Visual Studio 2015 업데이트 3 도구 집합을 사용하여 앱을 컴파일하고 연결하는 경우 나중에 재배포 가능 패키지를 사용할 수 있습니다. 2015년, 2017년, 2019년 및 2022년 라이브러리가 이전 버전 이진 호환성을 유지했기 때문입니다. 그 반대의 경우도 마찬가지입니다. 코드의 구성 요소를 빌드하는 데 사용한 것보다 이전 버전의 도구 집합에 재배포 가능 파일을 사용할 수 없습니다.

라이브러리

헤더 파일의 특정 버전인 경우 #include 결과 개체 파일을 동일한 버전의 라이브러리에 연결해야 합니다. 예를 들어 원본 파일에 Visual Studio 2015 업데이트 3 <immintrin.h>이 포함된 경우 Visual Studio 2015 업데이트 3 vcruntime 라이브러리와 연결해야 합니다. 마찬가지로 원본 파일에 Visual Studio 2017 버전 15.5 <iostream>가 포함된 경우 Visual Studio 2017 버전 15.5 표준 C++ 라이브러리 msvcprt와 연결해야 합니다. 혼합 및 일치는 지원되지 않습니다.

C++ 표준 라이브러리의 경우 Visual Studio 2010 이후 표준 헤더에서 혼합 및 일치를 명시적으로 사용할 #pragma detect_mismatch 수 없습니다. 호환되지 않는 개체 파일을 연결하려고 시도하거나 잘못된 표준 라이브러리와 연결하면 링크가 실패합니다.

이전 CRT 버전 혼합 및 일치는 지원되지 않았지만 시간이 지남에 따라 API 표면이 크게 변경되지 않았기 때문에 종종 작동했습니다. 앞으로 이전 버전과의 호환성을 유지할 수 있도록 유니버설 CRT에서는 이전 버전과의 호환성을 중단했습니다. 향후 버전이 지정된 새로운 유니버설 CRT 이진 파일을 도입할 계획이 없습니다. 대신, 기존 유니버설 CRT가 현재 위치에서 업데이트됩니다.

이전 버전의 Microsoft C 런타임 헤더로 컴파일된 개체 파일(및 라이브러리)과의 부분 링크 호환성을 제공하기 위해 Visual Studio 2015 이상과 함께 라이브러리 legacy_stdio_definitions.lib를 제공합니다. 이 라이브러리는 유니버설 CRT에서 제거된 대부분의 함수 및 데이터 내보내기에 대해 호환성 기호를 제공합니다. 제공된 호환성 기호 집합은 Windows SDK에 legacy_stdio_definitions.lib 포함된 라이브러리의 모든 종속성을 포함하여 대부분의 종속성을 충족하기에 충분합니다. 그러나 호환성 기호가 없는 일부 기호는 유니버설 CRT에서 제거되었습니다. 이러한 기호에는 일부 함수(예: __iob_func)와 일부 데이터 내보내기(예: __imp___iob, , __imp___pctype__imp___mb_cur_max)가 모두 포함됩니다.

이전 버전의 C 런타임 헤더를 사용하여 빌드된 정적 라이브러리가 있는 경우 다음 작업을 순서대로 수행하는 것이 좋습니다.

  1. 새로운 버전의 Visual Studio 및 유니버설 CRT 헤더를 사용하여 유니버설 CRT와의 연결을 지원하도록 고정 라이브러리를 다시 빌드합니다. 이 방법은 완벽하게 지원되며 최상의 옵션입니다.

  2. 정적 라이브러리를 다시 빌드할 수 없거나 다시 빌드하지 않으려는 경우 연결을 시도할 legacy_stdio_definitions.lib수 있습니다. 정적 라이브러리의 연결 시간 종속성을 충족하는 경우 이진 파일에 사용되는 정적 라이브러리를 철저히 테스트해야 합니다. 유니버설 CRT에 적용된 동작 변경으로 인해 부정적인 영향을 받지 않는지 확인합니다.

  3. 정적 라이브러리의 종속성이 충족 legacy_stdio_definitions.lib 되지 않거나 동작 변경으로 인해 라이브러리가 유니버설 CRT에서 작동하지 않을 수 있습니다. 이 경우 필요한 버전의 Microsoft C 런타임과 연결하는 DLL에 정적 라이브러리를 캡슐화하는 것이 좋습니다. 예를 들어 Visual Studio 2013을 사용하여 정적 라이브러리를 빌드한 경우 Visual Studio 2013 도구 집합 및 C++ 라이브러리를 사용하여 이 DLL을 빌드합니다. 라이브러리를 DLL로 빌드하면 특정 버전의 Microsoft C 런타임에 종속성이 있는 구현 세부 정보가 캡슐화됩니다. DLL 인터페이스는 DLL 경계malloc를 넘어 반환하거나 호출자가 해야 하는 할당된 포인터를 반환 FILE* 하는 경우처럼 DLL 인터페이스가 사용하는 C 런타임에 대한 세부 정보를 누출하지 않도록 주의해야 합니다free.

단일 프로세스에서 여러 CRT를 사용하는 것은 문제가 되지 않습니다. (실제로 대부분의 프로세스는 여러 CRT DLL을 로드합니다. 예를 들어 Windows 운영 체제 구성 요소는 의존 msvcrt.dll하며 CLR은 자체 프라이빗 CRT에 따라 달라집니다.) 다른 CRT에서 상태를 뒤섞을 때 문제가 발생합니다. 예를 들어 사용 하 여 msvcr110.dll!malloc 메모리를 할당 하 고 사용 하 여 msvcr120.dll!free해당 메모리의 할당을 취소 하려고 하지 말아야 하 고 사용 하 여 파일을 열고 사용 하 여 msvcr110!fopenmsvcr120!fread해당 FILE에서 읽으려고 시도 하지 말아야 합니다. 여러 CRT의 상태를 뒤섞지 않는 한 단일 프로세스에서 여러 CRT를 안전하게 로드할 수 있습니다.

자세한 내용은 코드를 유니버설 CRT로 업그레이드을 참조하세요.

프로젝트 설정으로 인한 오류

업그레이드 프로세스를 시작하려면 최신 버전의 Visual Studio에서 이전 프로젝트/솔루션/작업 영역을 엽니다. Visual Studio는 이전 프로젝트 설정에 따라 새 프로젝트를 만듭니다. 이전 프로젝트에 라이브러리 경로가 있는지 또는 비표준 위치에 하드 코딩된 경로가 포함되어 있는지 확인합니다. 프로젝트에서 기본 설정을 사용하는 경우 해당 경로의 파일이 컴파일러에 표시되지 않을 수 있습니다. 자세한 내용은 링커 OutputFile 설정을 참조하세요.

일반적으로 프로젝트 코드를 구성하여 프로젝트 기본 테넌트를 간소화하고 업그레이드된 코드를 최대한 빨리 빌드할 수 있습니다. 소스 코드가 이미 잘 구성되어 있고 이전 프로젝트가 Visual Studio 2010 이상에서 컴파일되는 경우 새 프로젝트 파일을 수동으로 편집하여 이전 컴파일러와 새 컴파일러 모두에서 컴파일을 지원할 수 있습니다. 다음 예제에서는 Visual Studio 2015와 Visual Studio 2017 둘 다에 대해 컴파일하는 방법을 보여 줍니다.

<PlatformToolset Condition="'$(VisualStudioVersion)'=='14.0'">v140</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)'=='15.0'">v141</PlatformToolset>

LNK2019: 확인할 수 없는 외부 참조

확인할 수 없는 기호의 경우 프로젝트 설정을 수정해야 할 수 있습니다.

  • 원본 파일이 기본이 아닌 위치에 있는 경우 프로젝트의 포함 디렉터리에 경로를 추가했나요?

  • 외부가 파일에 정의된 .lib 경우 프로젝트 속성에서 lib 경로를 지정했으며 해당 파일에 올바른 버전의 .lib 파일이 있나요?

  • 다른 버전의 Visual Studio로 .lib 컴파일된 파일에 연결하려고 합니까? 그렇다면 라이브러리 및 도구 집합 종속성에 대한 이전 섹션을 참조하세요.

  • 호출 사이트의 인수 형식이 함수의 기존 오버로드와 실제로 일치하나요? 함수 시그니처의 모든 typedef와 함수를 호출하는 코드 모두에서 기본 형식이 예상하는 형식인지 확인합니다.

해결되지 않은 기호 오류를 해결하려면 이진 파일에 정의된 기호를 검사하는 데 사용할 dumpbin.exe 수 있습니다. 다음 명령줄을 실행하여 라이브러리에 정의된 기호를 확인해 보세요.

dumpbin.exe /LINKERMEMBER somelibrary.lib

/Zc:wchar_t (wchar_t 네이티브 형식)

(Microsoft Visual C++ 6.0 이하 wchar_t 에서는 기본 제공 형식으로 구현되지 않았습니다. .)에 wchar.h 대한 unsigned shorttypedef로 선언되었습니다. C++ 표준에는 기본 제공 형식이 wchar_t 필요합니다. typedef 버전을 사용하면 이식성 문제가 발생할 수 있습니다. 이전 버전의 Visual Studio에서 업그레이드하고 코드가 암시적으로 변환 wchar_tunsigned short하려고 하기 때문에 컴파일러 오류 C2664가 표시되는 경우 코드를 변경하여 오류를 설정하는 대신 /Zc:wchar_t-수정하는 것이 좋습니다. 자세한 내용은 (wchar_t 네이티브 형식)을 참조 /Zc:wchar_t 하세요.

링커 옵션을 /NODEFAULTLIB/ENTRY사용하여 업그레이드 및/NOENTRY

링커 옵션(또는 모든 기본 라이브러리 링커 무시 속성)은 /NODEFAULTLIB 링커에 CRT와 같은 기본 라이브러리에 자동으로 연결하지 않도록 지시합니다. 이는 각 라이브러리가 개별 입력으로 나타나야 합니다. 이 라이브러리 목록은 프로젝트 속성 대화 상자의 링커 섹션에 있는 추가 종속성 속성에서 제공됩니다.

일부 기본 라이브러리의 콘텐츠가 리팩터링되었기 때문에 이 옵션을 사용하는 프로젝트는 업그레이드 시 문제가 발생합니다. 추가 종속성 속성이나 링커 명령줄에 각 라이브러리가 나열되어야 하기 때문에 현재 이름을 모두 사용하도록 라이브러리 목록을 업데이트해야 합니다.

다음 표에서는 Visual Studio 2015부터 콘텐츠가 변경된 라이브러리를 보여 줍니다. 업그레이드하려면 첫 번째 열의 라이브러리에 두 번째 열의 이름을 추가해야 합니다. 이러한 라이브러리 중 일부는 가져오기 라이브러리이지만 중요하지 않습니다.

기존 이름 다음 라이브러리를 사용해야 합니다.
libcmt.lib libcmt.lib, libucrt.lib, libvcruntime.lib
libcmtd.lib libcmtd.lib, libucrtd.lib, libvcruntimed.lib
msvcrt.lib msvcrt.lib, ucrt.lib, vcruntime.lib
msvcrtd.lib msvcrtd.lib, ucrtd.lib, vcruntimed.lib

기본 라이브러리를 건너뛰는 효과가 있는 /ENTRY 옵션 또는 /NOENTRY 옵션을 사용하는 경우에도 같은 문제가 적용됩니다.

향상된 언어 규칙으로 인한 오류

Microsoft C++ 컴파일러는 지난 몇 년 동안 C++ 표준에 대한 규칙을 지속적으로 향상시켜 왔습니다. 이전 버전에서 컴파일된 코드는 이후 버전의 Visual Studio에서 컴파일되지 않을 수 있습니다. 컴파일러가 이전에 무시되었거나 명시적으로 허용한 오류에 올바르게 플래그를 지정하기 때문입니다.

예를 들어 /Zc:forScope 스위치는 MSVC 기록의 초기에 도입되었습니다. 루프 변수에 대해 비준수 동작을 허용합니다. 해당 스위치는 이제 사용되지 않으며 이후 버전에서 제거될 수 있습니다. 코드를 업그레이드할 때는 해당 스위치를 사용하지 않는 것이 좋습니다. 자세한 내용은 사용되지 않음을 참조 /Zc:forScope- 하세요.

업그레이드할 때 표시될 수 있는 일반적인 컴파일러 오류 중 한 가지 예는 비 const 인수가 const 매개 변수에 전달되는 경우입니다. 이전 버전의 컴파일러가 항상 오류로 플래그를 지정하지는 않았습니다. 자세한 내용은 컴파일러의 보다 엄격한 변환을 참조하세요.

특정 규칙 향상에 대한 자세한 내용은 Visual C++ 변경 기록 2003~2015Visual Studio의 C++ 규칙 향상을 참조하세요.

정수 형식과 관련된 <stdint.h> 오류

헤더는 <stdint.h> 기본 제공 정수 형식과 달리 모든 플랫폼에서 지정된 길이가 보장되는 typedef 및 매크로를 정의합니다. 예를 들면 uint32_tint64_t입니다. 헤더가 <stdint.h> Visual Studio 2010에 추가되었습니다. 2010년 이전에 작성된 코드는 해당 형식에 대한 프라이빗 정의를 제공했을 수 있습니다. 그리고 이러한 정의가 항상 정의와 <stdint.h> 일치하지 않을 수도 있습니다.

오류가 C2371이고 stdint 형식이 관련된 경우 코드 또는 타사 라이브러리 파일의 헤더에 형식이 정의되어 있음을 의미합니다. 업그레이드할 때는 형식의 <stdint.h> 사용자 지정 정의를 제거해야 하지만 먼저 사용자 지정 정의를 현재 표준 정의와 비교하여 새 문제가 발생하지 않도록 해야 합니다.

F12(정의로 이동) 키를 눌러 해당 형식이 정의된 위치를 확인할 수 있습니다.

/showIncludes 컴파일러 옵션은 여기에서 유용할 수 있습니다. 프로젝트의 속성 페이지 대화 상자에서 구성 속성>C/C++>고급 페이지를 선택하고 포함 표시를 예설정합니다. 그런 다음 프로젝트를 다시 빌드합니다. 출력 창에 파일 목록이 #include 표시됩니다. 각 헤더는 포함하는 헤더 아래에 들여쓰기됩니다.

CRT 함수와 관련된 오류

지난 몇 년 동안 C 런타임에서 많은 변화가 있었습니다. 함수의 보안 버전이 많이 추가되었으며 일부는 제거되었습니다. 또한 이 문서의 앞부분에서 설명한 대로 Microsoft의 CRT 구현은 Visual Studio 2015에서 새 이진 파일 및 관련 파일로 리팩터링되었습니다 .lib .

오류가 CRT 함수와 관련된 경우 Visual C++ 변경 기록 2003~2015 또는 Visual Studio의 C++ 규칙 향상을 검색하여 해당 문서에 추가 정보가 들어 있는지 확인합니다. 오류가 LNK2019 경우 함수가 제거되지 않았는지 확인합니다. 그렇지 않은 경우 함수가 여전히 존재하고 호출 코드가 올바른 경우 프로젝트에서 사용하는/NODEFAULTLIB지 여부를 검사. 그렇다면 새 UCRT(유니버설) 라이브러리를 사용하도록 라이브러리 목록을 업데이트해야 합니다. 자세한 내용은 라이브러리 및 종속성에 대한 위 섹션을 참조하세요.

오류가 발생하는 printf 경우 또는 scanf다음을 포함하지 stdio.h않고 함수를 비공개로 정의하지 않는지 확인합니다. 그렇다면 프라이빗 정의를 제거하거나 에 연결합니다 legacy_stdio_definitions.lib. 추가 종속성 속성에 있는 구성 속성>링커>입력 아래의 속성 페이지 대화 상자에서 이 라이브러리를 설정할 수 있습니다. Windows SDK 8.1 이전 버전에 연결하는 경우 추가 legacy_stdio_definitions.lib합니다.

오류가 형식 문자열 인수와 관련된 경우 컴파일러가 표준 적용에 대해 보다 엄격하기 때문일 수 있습니다. 자세한 내용은 변경 기록을 참조하세요. 여기에 포함된 오류는 잠재적으로 보안 위험을 나타낼 수 있으므로 특히 주의하세요.

C++ 표준의 변경으로 인한 오류

C++ 표준 자체는 항상 이전 버전과 호환되지 않는 방식으로 발전했습니다. C++11에는 이동 의미 체계, 새로운 키워드(keyword) 및 기타 언어 및 표준 라이브러리 기능이 도입되었습니다. 이러한 변경으로 인해 컴파일러 오류와 런타임 동작이 달라질 수 있습니다.

예를 들어 이전 C++ 프로그램에는 헤더가 iostream.h 포함될 수 있습니다. 이 헤더는 C++의 초기에 사용이 중단되었으며 결국 Visual Studio에서 완전히 제거되었습니다. 이 경우 코드를 사용하고 <iostream> 다시 작성해야 합니다. 자세한 내용은 이전 iostream 코드 업데이트를 참조하세요.

C4838: 축소 변환 경고

이제 C++ 표준은 서명되지 않은 정수 값에서 부호 있는 정수 값으로의 변환이 축소되도록 지정합니다. 컴파일러는 Visual Studio 2015 이전에 이 경고를 발생하지 않았습니다. 각 항목을 검사하여 축소가 코드의 정확성에 영향을 주지 않는지 확인합니다.

보안 CRT 함수를 사용하도록 경고

지난 몇 년 동안 C 런타임 함수의 보안 버전이 도입되었습니다. 오래된 비보안 버전도 계속 사용할 수 있지만 보안 버전을 사용하도록 코드를 변경하는 것이 좋습니다. 컴파일러에서 비보안 버전의 사용에 대한 경고가 발생합니다. 이러한 경고를 사용하지 않거나 무시하도록 선택할 수 있습니다. 솔루션의 모든 프로젝트에 대해 경고를 사용하지 않으려면 보기>속성 관리자를 열고, 경고를 사용하지 않을 프로젝트를 모두 선택한 다음, 선택한 항목을 마우스 오른쪽 단추로 클릭하고, 속성을 선택합니다. 구성 속성>C/C++>고급 아래의 속성 페이지 대화 상자에서 특정 경고 사용 안 함을 선택합니다. 드롭다운 화살표를 선택한 다음 편집을 선택합니다. 텍스트 상자에 4996을 입력합니다. ('C' 접두사를 포함하지 마세요.) 자세한 내용은 보안 CRT를 사용하도록 포팅을 참조하세요.

Windows API 또는 사용되지 않는 SDK의 변경으로 인한 오류

지난 몇 년 동안 Windows API와 데이터 형식이 추가되었으며, 때로는 변경되거나 제거되었습니다. 또한 핵심 운영 체제에 속하지 않은 다른 SDK도 오고 갔습니다. 이전 프로그램에는 더 이상 존재하지 않는 API에 대한 호출이 포함될 수 있습니다. 더 이상 지원되지 않는 다른 Microsoft SDK의 API 호출도 포함될 수 있습니다. 이전 Microsoft SDK에서 누락된 Windows API 또는 API에 대한 오류가 표시될 수 있습니다. API가 제거되거나 더 안전한 최신 함수로 대체되었을 수 있습니다.

Windows API 설명서에는 지원되는 최소 또는 최대 운영 체제가 나열됩니다. 특정 Windows API에 대한 자세한 내용은 데스크톱 Windows 애플리케이션에 대한 API 인덱스를 참조하세요.

Windows 버전

Windows API를 직접 또는 간접적으로 사용하는 프로그램을 업그레이드하는 경우 지원할 최소 Windows 버전을 결정해야 합니다. 대부분의 경우 Windows 7을 선택하는 것이 좋습니다. 자세한 내용은 헤더 파일 문제를 참조하세요. WINVER 매크로는 프로그램이 실행되도록 설계된 가장 오래된 Windows 버전을 정의합니다. MFC 프로그램이 0x0501(Windows XP)로 설정 WINVER 되면 컴파일러 도구 집합 자체에 XP 모드가 있더라도 MFC가 더 이상 XP를 지원하지 않으므로 경고가 표시됩니다. Windows XP에 대한 컴파일러 도구 집합 지원은 Visual Studio 2017에서 종료되었습니다.

자세한 내용은 대상 창 버전 업데이트 및 더 오래된 헤더 파일을 참조하세요.

ATL/MFC

ATL 및 MFC는 비교적 안정된 API이지만 때때로 변경됩니다. 자세한 내용은 Visual C++ 변경 기록 2003 - 2015, Visual Studio의 Visual C++의 새로운 기능 및 Visual Studio의 C++ 규칙 향상을 참조하세요.

LNK 2005 _DllMain@12 MSVCRTD.lib에 이미 정의되어 있습니다.

이 오류는 MFC 애플리케이션에서 발생할 수 있습니다. CRT 라이브러리와 MFC 라이브러리 간의 순서 지정 문제를 나타냅니다. MFC는 먼저 연결되어야 합니다. 따라서 MFC가 제공되고 delete 연산자가 제공 new 되어야 합니다. 오류를 해결하려면 스위치를 /NODEFAULTLIB 사용하여 다음 기본 라이브러리를 mfcs140d.lib무시합니다. MSVCRTD.lib 그런 다음 이러한 동일한 라이브러리를 추가 종속성으로 추가합니다.

32비트 및 64비트

원래 코드가 32비트 시스템에 대해 컴파일된 경우 새 32비트 앱 대신 64비트 버전을 만들 수 있습니다. 일반적으로 먼저 32비트 모드로 프로그램을 컴파일한 다음 64비트를 시도해야 합니다. 64비트용 컴파일 작업은 간단하지만, 경우에 따라 32비트 빌드에서 숨겨진 버그가 나타날 수 있습니다.

또한 포인터 크기, 시간 및 크기 값 및 함수의 크기별 형식 지정자와 printfscanf 관련된 가능한 컴파일 시간 및 런타임 문제를 알고 있어야 합니다. 자세한 내용은 64비트, x64 대상일반적인 Visual C++ 64비트 마이그레이션 문제에 대한 Visual C++ 구성을 참조하세요. 마이그레이션 팁에 대한 자세한 내용은 64비트 Windows에 대한 프로그래밍 가이드를 참조 하세요.

유니코드 및 멀티바이트 문자 집합(MBCS)/ASCII

유니코드가 표준화되기 전에는 많은 프로그램에서 MBCS(멀티바이트 문자 집합)를 사용하여 ASCII 문자 집합에 포함되지 않은 문자를 표시했습니다. 이전 MFC 프로젝트에서 MBCS는 기본 설정이었습니다. 이러한 프로그램을 업그레이드하면 대신 유니코드를 사용하는 것이 좋습니다. 유니코드로의 변환이 개발 비용 가치가 없다고 판단되면 경고를 사용하지 않도록 설정하거나 무시하도록 선택할 수 있습니다. 솔루션의 모든 프로젝트에 대해 경고를 사용하지 않으려면 보기>속성 관리자를 열고, 경고를 사용하지 않을 프로젝트를 모두 선택한 다음, 선택한 항목을 마우스 오른쪽 단추로 클릭하고, 속성을 선택합니다. 속성 페이지 대화 상자에서 구성 속성>C/C++>고급을 선택합니다. 특정 경고 사용 안 함 속성에서 드롭다운 화살표를 연 다음, 편집을 선택합니다. 텍스트 상자에 4996을 입력합니다. ('C' 접두사를 포함하지 마세요.) 확인을 선택하여 속성을 저장한 다음 확인을 선택하여 변경 내용을 저장합니다.

자세한 내용은 MBCS에서 유니코드로 포팅을 참조하세요. MBCS 및 유니코드에 대한 일반적인 내용은 Visual C++ 및 국제화의 텍스트 및 문자열을 참조하세요.

참고 항목

이전 버전의 Visual C++에서 프로젝트 업그레이드
Visual Studio의 C++ 규칙 향상