다음을 통해 공유


방법: 다음으로 마이그레이션 /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++에서 키워드(keyword) 발생하는 C 코드에서 사용되는 식별자(예: virtual, new, deletebool, 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 프로그래밍에 대한 자세한 내용은 다음을 참조하세요.

참고 항목

혼합형(네이티브 및 관리) 어셈블리