2017-02-26 15 views
4

관리되는 C++이 어떻게 작동하고 컴파일되는지 이해하는 데 문제가 있습니다.Managed C++ 이해

.NET Framework에서 C#/VB/F #/.. 등으로 코드를 개발할 수 있습니다. 이 모든 언어는 Java 바이트 코드와 유사한 CIL (Common Intermediate Language)로 컴파일됩니다. 이론적으로 CIL은 모든 플랫폼에 탑재 될 수 있습니다 (Mono는 실용적이었습니다). Windows에서 CLR은 CIL을 네이티브 코드 JIT (Just-In-Time)로 컴파일하고 모든 것이 원활하게 실행되고 원활하게 진행됩니다.

Managed C++는 어떻게 컴파일됩니까? CIL 코드로 컴파일하고 JIT를 사용하여 CLR이 실행될 때까지 기다릴 수 있습니까? 관리 C++는 표준 C++ 코드 (CIL로 컴파일되지 않음)를 사용할 수 있으므로 생각하지 않습니다. 또한 .NET 어셈블리 (CIL)를 어떻게 사용할 수 있습니까?

어떤 도움을 주셔서 감사합니다. 감사

편집 : 나는이 answer을 보았다

. C++/CLI에서 관리 코드가 MSIL로 컴파일되고 비 관리 코드를 네이티브 코드 또는 MSIL로 컴파일 할 수있는 옵션이 있습니다. 따라서 .NET 어셈블리를 호출하는 방법을 이해합니다.

어쨌든 비 관리 코드가 네이티브 코드로 컴파일 된 경우 C++ 비 관리 코드가 동일한 어셈블리에서 관리되는 코드와 함께 실행되는 방식을 여전히 이해할 수 없습니다. 어떤 아이디어?

답변

6

: 당신은 또한 이러한 .NET 어셈블리가 조립에 프로젝트에서 참조를 추가하고 코드를 추가 호출하는 interoperabilitybetween 네이티브 코드와 .NET 코드 를 위해 중대하다, 기본 전화를 사용할 수 있습니다 매우 껄끄 러운 구현 세부 사항이 있습니다. 그들 모두를 다루기는 어렵지만, 그 질문에는 약간의 오해가 있습니다. 그 문제를 해결하고 다음 단계로 나아갈 수 있습니다.

또한 .NET 어셈블리 (CIL)를 어떻게 사용할 수 있습니까?

는 다만 CIL은 링커 혼합 모드 어셈블리를 생성한다. .NET 메타 데이터 + msil 네이티브 코드가 모두 들어 있습니다. 사실, OS 로더에 관한 한, 그것은 정상적인 실행 파일의 네이티브 코드입니다. 네이티브 C++ 컴파일러에서 생성되는 종류와 다릅니다. 순수한 원시 실행 가능 이미지처럼로드되고 재배치됩니다. 괴상한 .NET 메타 데이터 + msil입니다. 로더는 데이터 덩어리처럼 보이지만, 전혀 접하지 않습니다. CLR 만 수행합니다.

은 ...

이 매우 정확하고, 네이티브 C++ 코드가 또는 기계 코드를 MSIL을 컴파일 할 수 없음 (CIL에 컴파일되지 않음) 표준 C++ 코드를 사용합니다. 얻을 수있는 것은/clr 컴파일 옵션이 사용되었는지 아니면 함수 수준에서 적용된 #pragma managed가 사용되었는지에 따라 다릅니다. CIL은 Java JVM에서 사용되는 바이트 코드와 잘 비교하지 않습니다. 더 강력하고 C++ 03 호환 네이티브 C++ 코드를 지원할 수 있습니다. 때로는 reverse pinvoke (네이티브 코드 호출 관리 코드)를 활용하기 위해이 작업을 수행하는 경우가 있습니다.때로는 우연히 이루어지며 너무 많은 원시 C++ 코드가 msil로 컴파일됩니다. 지터에 의해 생성 된 기계 코드는 최적이 아니며 (시간 제약 조건 하에서 최적화 됨) 어떠한 방식으로도 관리되지 않습니다. 그것은 검증 할 수없고 가비지 컬렉터 사랑을 얻지 못합니다.

CIL을위한 최상의 정신 이미지는 프론트 엔드 (파서)와 백엔드 (코드 생성기 및 최적화 프로그램) 간의 모든 원시 C++ 컴파일러에서 사용되는 중간 표현입니다. 종종 보이지 않는 구현 세부 사항이지만 LLVM을 사용하는 C++ 컴파일러를 사용할 때 더 눈에.니다 (Clang처럼). .NET Just-In-Time 컴파일러는 런타임시 LLVM이 컴파일 할 때 수행하는 작업을 수행합니다.


대부분의 프로그래머는 관리 코드는 네이티브 코드 (또는 그 반대)를 호출 할 때 거대한 모드 스위치의 정신적 이미지가 발생되고있다. 그것은 전혀 정확하지 않습니다. this post에서 C++ 컴파일러의 백엔드가 생성 한 기계 코드와 지터의 차이점을 볼 수 있습니다. 핵심은 거의 동일하므로 관리 코드가 원시 코드와 경쟁 할 수 있도록하는 필수 기능입니다. 네이티브 코드를 호출하는 관리 코드가 다른 방식으로 어떻게 특수한 코드인지 파악하는 데 도움이됩니다.

또 다른 오해는 관리되는 코드가 자동으로 안전하다는 것입니다. 사실이 아닙니다. C#과 같은 언어는 C++로 할 수있는 것처럼 스택에서 포인터와 낙서로 파티를 할 수 있으며, 그렇게 쉽게 메모리를 손상시킬 수 있습니다. 그것은 단지 더 나은 파티션입니다, 그것은 당신이 unsafe 키워드로 그것에 대해 명시 적으로 강요합니다. C++/CLI에 그러한 제약 조건이 없어도 아무 것도 할 수 없습니다.

관리 코드와 기본 코드의 근본적인 차이점은 msil을 컴파일 할 때 지터가 생성하는 데이터 구조입니다. 네이티브 컴파일러에서 가져 오지 않는 추가 데이터. 그 데이터는 가비지 컬렉터에 의해 요구되며 객체 루트를 찾는 방법을 알려줍니다. 해당 데이터에 대한 자세한 내용은 this post입니다. 해당 데이터를 준수하고 GC가 작업을 완료하도록 허용하면 런타임에 관리되는 코드가 약간 느려지 게됩니다.

+0

좋은 답변입니다. 특히 CIL은 자바 JVM에서 사용되는 바이트 코드와 비교하지 못하며 더욱 강력하고 C++ 03 호환 네이티브 C++ 코드를 지원할 수 있습니다. " 자바 작업을 할 때 바이트 코드 스펙을보고 울었다. – hoodaticus

0

Manged C++는 더 이상 사용되지 않습니다. 오늘 네이티브 C++ 및 Manged 코드를 작성하려면 C++ \ CLI를 사용해야합니다. CLR을 준수하고 다른 .net 어셈블리를 실행할 수 있습니다. 그것은 큰 주제입니다

using namespace System; 
+1

C++/CLI에 대한 참고 사항을 고맙게 생각합니다. 그러나 C++/CLI의 관리되지 않는 부분을 기본 코드 (비 MSIL)로 컴파일 할 수 있습니다. 그렇다면 코드의 관리 부분이 MSIL로 강제 컴파일되기 때문에 어떻게 작동합니까? – Everyone

+1

@ 모든 파일 형식은 여전히 ​​PE 파일이며 다른 것과 마찬가지로 네이티브 코드를 포함 할 수 있습니다 (상호 이식성을 희생시키면서). [calli] (https://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.calli (v = vs.110) .aspx) 명령을 사용하여 기본 메서드를 호출 할 수 있습니다 . –

+0

C++/CLI를 기본 (전용)으로 컴파일 할 수없는 경우. 관리 코드에 대한 문의가있는 경우 –