방법: 다음으로 마이그레이션 /clr
이 문서에서는 네이티브 코드를 .으로 /clr
컴파일할 때 발생하는 문제에 대해 설명합니다. 자세한 내용은 /clr(공용 언어 런타임 컴파일)을 참조하세요. /clr
를 사용하면 네이티브 C++ 코드가 다른 네이티브 C++ 코드 외에도 .NET 어셈블리에서 호출되고 호출될 수 있습니다. 컴파일/clr
의 이점에 대한 자세한 내용은 Mixed(네이티브 및 관리형) 어셈블리와 네이티브 및 .NET 상호 운용성을 참조하세요.
을 사용하여 라이브러리 프로젝트를 컴파일하는 알려진 문제 /clr
Visual Studio에는 다음을 사용하여 라이브러리 프로젝트를 컴파일할 때 알려진 몇 가지 문제가 포함되어 있습니다 /clr
.
코드는 런타임에 .를 사용하여 형식을
CRuntimeClass::FromName
쿼리할 수 있습니다. 그러나 형식이 MSIL DLL(컴파일됨/clr
)에 있는 경우 정적 생성자가 관리되는 DLL에서 실행되기 전에 발생하는 경우 호출FromName
이 실패할 수 있습니다. (코드가 관리되는 DLL에서FromName
실행된 후에 호출이 발생하는 경우 이 문제가 표시되지 않습니다.) 이 문제를 해결하려면 관리되는 정적 생성자를 강제로 생성할 수 있습니다. 관리되는 DLL에서 함수를 정의하고, 내보내고, 네이티브 MFC 애플리케이션에서 호출합니다. 예시:// MFC extension DLL Header file: __declspec( dllexport ) void EnsureManagedInitialization () { // managed code that won't be optimized away System::GC::KeepAlive(System::Int32::MaxValue); }
Visual C++를 사용하여 컴파일
프로젝트의 모듈에서 사용하기 /clr
전에 먼저 네이티브 프로젝트를 Visual Studio와 컴파일하고 연결합니다.
다음 단계를 순서대로 수행하여 컴파일에 대한 가장 쉬운 경로를 /clr
제공합니다. 이러한 각 단계 후에 프로젝트를 컴파일하고 실행하는 것이 중요합니다.
이전 버전의 Visual Studio에서 업그레이드
이전 버전에서 Visual Studio를 업그레이드하는 경우 Visual Studio의 향상된 표준 C++ 규칙과 관련된 컴파일러 오류가 표시될 수 있습니다.
이전 버전의 Visual Studio를 사용하여 빌드된 프로젝트도 먼저 없으면 /clr
컴파일해야 합니다. 이제 Visual Studio에서 표준 C++ 규칙 및 일부 호환성이 손상되는 변경이 증가했습니다. 가장 주의가 필요할 수 있는 변경 내용은 CRT의 보안 기능입니다. CRT를 사용하는 코드는 사용 중단 경고를 생성할 가능성이 높습니다. 이러한 경고는 표시되지 않을 수 있지만, 더 나은 보안을 제공하고 코드에서 보안 문제가 표시될 수 있으므로 새로운 보안 강화 버전의 CRT 함수 로 마이그레이션하는 것이 좋습니다.
C++용 관리되는 확장에서 업그레이드
Visual Studio 2005 이상 버전에서는 C++용 관리되는 확장으로 작성된 코드는 아래에서 /clr
컴파일되지 않습니다.
C 코드를 C++로 변환
Visual Studio는 C 파일을 컴파일하지만 컴파일을 위해 C++ /clr
로 변환해야 합니다. 실제 파일 이름은 변경할 필요가 없습니다. 사용할 /Tp
수 있습니다(참조/Tc
, /Tp
, /TC
/TP
(원본 파일 형식 지정). C++ 소스 코드 파일은 필수 /clr
이지만 개체 지향 패러다임을 사용하도록 코드를 리팩터링할 필요는 없습니다.
C 코드는 C++ 파일로 컴파일될 때 변경이 필요할 수 있습니다. C++ 형식 안전 규칙은 엄격하므로 캐스트를 사용하여 형식 변환을 명시적으로 설정해야 합니다. 예를 들어 malloc는 void 포인터를 반환하지만 캐스트가 있는 C의 모든 형식에 대한 포인터에 할당할 수 있습니다.
int* a = malloc(sizeof(int)); // C code
int* b = (int*)malloc(sizeof(int)); // C++ equivalent
또한 함수 포인터는 C++에서도 형식이 안전하므로 다음 C 코드를 수정해야 합니다. C++에서는 함수 포인터 형식을 typedef
정의하는 형식을 만든 다음, 해당 형식을 사용하여 함수 포인터를 캐스팅하는 것이 가장 좋습니다.
NewFunc1 = GetProcAddress( hLib, "Func1" ); // C code
typedef int(*MYPROC)(int); // C++ equivalent
NewFunc2 = (MYPROC)GetProcAddress( hLib, "Func2" );
또한 C++에서는 함수를 참조하거나 호출하기 전에 프로토타입을 만들거나 완전히 정의해야 합니다.
C++에서 키워드로 발생하는 C 코드에서 사용되는 식별자(예: virtual
, new
, delete
, bool
true
, false
등)의 이름을 바꿔야 합니다. 이 변경은 일반적으로 간단한 검색 및 바꾸기 작업으로 수행할 수 있습니다.
COMObj1->lpVtbl->Method(COMObj, args); // C code
COMObj2->Method(args); // C++ equivalent
프로젝트 설정 다시 구성
Visual Studio에서 프로젝트를 컴파일하고 실행한 후에는 기본 구성을 /clr
수정하는 대신 새 프로젝트 구성을 만들어야 합니다. /clr
는 일부 컴파일러 옵션과 호환되지 않습니다. 별도의 구성을 만들면 프로젝트를 네이티브 또는 관리형으로 빌드할 수 있습니다. /clr
속성 페이지 대화 상자에서 선택하면 호환되지 않는 /clr
프로젝트 설정이 비활성화됩니다. (나중에 선택되지 않은 경우 /clr
비활성화된 옵션은 자동으로 복원되지 않습니다.)
새 프로젝트 구성 만들기
새 프로젝트 구성 대화 상자(Build>Configuration Manager>활성 솔루션 구성>새로 만들기)에서 [설정 복사] 옵션을 사용하여 기존 프로젝트 설정에 따라 프로젝트 구성을 만들 수 있습니다. 디버그 구성에 대해 구성 복사본을 한 번, 릴리스 구성에 대해 한 번 만듭니다. 이후 변경 내용은 원래 프로젝트 구성을 /clr
그대로 유지하여 특정 구성에만 적용할 수 있습니다.
사용자 지정 빌드 규칙을 사용하는 프로젝트에는 각별한 주의가 필요할 수 있습니다.
이 단계는 메이크파일을 사용하는 프로젝트에 다른 영향을 미칩니다. 이 경우 별도의 빌드 대상을 구성하거나 원래 복사본에서 컴파일 관련 /clr
버전을 만들 수 있습니다.
프로젝트 설정 변경
/clr
는 /clr(공용 언어 런타임 컴파일)의 지침에 따라 개발 환경에서 선택할 수 있습니다. 앞에서 설명한 것처럼 이 단계에서는 충돌하는 프로젝트 설정을 자동으로 사용하지 않도록 설정합니다.
참고 항목
Visual Studio 2003 /Zl
에서 관리되는 라이브러리 또는 웹 서비스 프로젝트를 업그레이드할 때 컴파일러 옵션이 명령줄 속성 페이지에 추가됩니다. 이로 인해 LNK2001 오류가 발생합니다. 명령줄 속성 페이지에서 제거 /Zl
하여 오류를 해결합니다. 자세한 내용은 /Zl
(기본 라이브러리 이름 생략) 및 컴파일러 및 빌드 속성 설정을 참조하세요.
메이크파일로 빌드된 프로젝트의 경우 호환되지 않는 컴파일러 옵션이 추가되면 /clr
수동으로 사용하지 않도록 설정해야 합니다. 호환 /clr
되지 않는 컴파일러 옵션에 대한 자세한 내용은 제한을 참조 /clr
하세요.
미리 컴파일된 헤더
미리 컴파일된 헤더는 .에서 /clr
지원됩니다. 그러나 CPP 파일 /clr
중 일부만 컴파일하는 경우(나머지는 네이티브로 컴파일) 일부 변경이 필요합니다. 미리 컴파일된 헤더는 /clr
메타데이터를 생성하고 필요하기 때문에 /clr
미리 컴파일된 헤더와 /clr
호환되지 않습니다. 컴파일된 /clr
모듈은 메타데이터를 포함하지 않는 미리 컴파일된 헤더를 사용할 수 없으며, 비-/clr
모듈은 메타데이터를 포함하는 미리 컴파일된 헤더 파일을 사용할 수 없습니다.
일부 모듈이 컴파일되는 프로젝트를 컴파일하는 가장 쉬운 방법은 미리 컴파일된 /clr
헤더를 완전히 사용하지 않도록 설정하는 것입니다. (프로젝트 속성 페이지 대화 상자에서 다음을 엽니다.C/C++ 노드를 선택하고 미리 컴파일된 헤더를 선택합니다. 그런 다음 미리 컴파일된 헤더 만들기/사용 속성을 "미리 컴파일된 헤더를 사용하지 않음"으로 변경합니다.)
그러나 특히 대규모 프로젝트의 경우 미리 컴파일된 헤더는 훨씬 더 나은 컴파일 속도를 제공하므로 이 기능을 사용하지 않도록 설정하는 것은 바람직하지 않습니다. 이 경우 미리 컴파일된 별도의 헤더를 /clr
사용하도록 파일 및 비 파일을/clr
구성하는 것이 가장 좋습니다. 한 단계에서 구성할 수 있습니다. 솔루션 탐색기 사용하여 컴파일 /clr
할 모듈을 다중 선택합니다. 그룹을 마우스 오른쪽 단추로 클릭하고 속성을 선택합니다. 그런 다음 PCH Through File 및 미리 컴파일된 헤더 파일 속성을 모두 변경하여 각각 다른 헤더 파일 이름과 PCH 파일을 사용합니다.
오류 수정
코드를 /clr
컴파일하면 컴파일러, 링커 또는 런타임 오류가 발생할 수 있습니다. 이 섹션에서는 가장 일반적인 문제에 대해 설명합니다.
메타데이터 병합
데이터 형식의 버전이 다르면 두 형식에 대해 생성된 메타데이터가 일치하지 않으므로 링커가 실패할 수 있습니다. (형식의 멤버를 조건부로 정의할 때 오류가 발생하지만 형식을 사용하는 모든 CPP 파일의 조건은 동일하지 않습니다.) 이 경우 링커가 실패하여 형식이 정의된 두 번째 OBJ 파일의 이름과 기호 이름만 보고합니다. OBJ 파일이 링커로 전송되는 순서를 회전하여 다른 버전의 데이터 형식 위치를 검색하는 것이 유용할 수 있습니다.
로더 잠금 교착 상태
"로더 잠금 교착 상태"는 발생할 수 있지만 결정적이며 런타임에 검색되고 보고됩니다. 자세한 배경, 지침 및 솔루션은 혼합 어셈블리 초기화를 참조하세요.
데이터 내보내기
DLL 데이터를 내보내는 것은 오류가 발생하기 쉬울 수 있으며 코드에서는 /clr
권장되지 않습니다. DLL의 일부 관리되는 부분이 실행될 때까지 DLL의 데이터 섹션 초기화가 보장되지 않기 때문입니다. 지시문을 사용하여 #using
메타데이터를 참조합니다.
형식 표시 유형
네이티브 형식은 기본적으로 사용됩니다 private
. 네이 private
티브 형식은 DLL 외부에 표시되지 않습니다. 이러한 형식에 추가하여 public
이 오류를 해결합니다.
부동 소수점 및 맞춤 문제
__controlfp
는 공용 언어 런타임에서 지원되지 않습니다. (자세한 내용은 , __control87_2
_controlfp
. 참조)_control87
또한 CLR은 을(를) 존중align
하지 않습니다.
COM 초기화
공용 언어 런타임은 모듈이 초기화될 때 자동으로 COM을 초기화합니다(COM이 자동으로 초기화되면 MTA로 수행됨). 따라서 COM을 명시적으로 초기화하면 COM이 이미 초기화되었음을 나타내는 반환 코드가 생성됩니다. CLR이 이미 COM을 다른 스레딩 모델로 초기화한 경우 한 스레딩 모델로 COM을 명시적으로 초기화하려고 하면 애플리케이션이 실패할 수 있습니다.
공용 언어 런타임은 기본적으로 COM을 MTA로 시작합니다. USE(CLR 스레드 특성 설정)를 사용하여 /CLRTHREADATTRIBUTE
COM 모델을 수정합니다.
성능 문제
MSIL에 생성된 네이티브 C++ 메서드가 간접적으로 호출될 때(가상 함수 호출을 통해 또는 함수 포인터를 사용하여) 성능이 저하될 수 있습니다. 자세한 내용은 Double Thunking을 참조하세요.
네이티브에서 MSIL로 이동하면 작업 집합의 크기가 증가합니다. 이러한 증가는 공용 언어 런타임이 프로그램이 올바르게 실행되도록 하는 많은 기능을 제공하기 때문에 발생합니다. /clr
애플리케이션이 제대로 실행되지 않는 경우 기본 컴파일러 경고(수준 1 및 3) C4793을 사용하도록 설정할 수 있습니다.
종료할 때 프로그램 충돌
경우에 따라 관리 코드 실행이 완료되기 전에 CLR을 종료할 수 있습니다. 사용 중 std::set_terminate
이며 SIGTERM
종료가 발생할 수 있습니다. 자세한 내용은 상수 및 을 참조 signal
하세요.set_terminate
새 Visual C++ 기능 사용
애플리케이션이 컴파일, 링크 및 실행된 후에는 컴파일된 /clr
모든 모듈에서 .NET 기능을 사용할 수 있습니다. 자세한 내용은 Component Extensions for Runtime Platforms을 참조하세요.
Visual C++의 .NET 프로그래밍에 대한 자세한 내용은 다음을 참조하세요.