C++/CLI
C++/CLI패러다임 | 구조화된, 명령적인, 객체 지향적인 |
---|---|
가족 | C |
설계자 | 마이크로소프트 |
개발자 | 마이크로소프트 |
첫 등장 | 2005; |
플랫폼 | 공통 언어 인프라 |
웹사이트 | docs |
영향을 받음 | |
C++, C++, C#에 대한 중앙 관리 확장 |
C++/CLI는 공통 언어 인프라를 위해 수정된 C++ 프로그래밍 언어의 변형입니다. Visual Studio 2005 이후 버전의 일부이며 다른 버전과의 상호 운용성을 제공합니다.C#과 같은 NET 언어. Microsoft는 C++/CLI를 C++용 Managed Extensions를 대체하기 위해 만들었습니다. 2005년 12월, Ecma International은 ECMA-372 표준으로 C++/CLI 규격을 발표했습니다.[1]
구문 변경사항
C++/CLI는 C++ 슈퍼셋 지향의 Managed C++(MC++)(비표준 키워드가 다음과 같이 스타일화된)가 아닌 자체 언어(예: 새로운 키워드 집합 포함)로 간주되어야 합니다. __gc
아니면 __value
). 이 때문에 특히 모호한 식별자의 제거와 의 추가와 관련하여 몇 가지 주요 구문 변화가 있습니다.NET 특정 기능.
여러 버전의 연산자와 같은 많은 충돌 구문 new()
MC++에서는 분할되었습니다: C++/CLI에서는 .NET 참조 유형이 새 키워드로 생성됩니다. gcnew
(즉, 쓰레기 수집된 새로운 ()). 또한 C++/CLI는 에서 제네릭의 개념을 도입했습니다.NET(가장 일반적인 목적의 경우 표준 C++ 템플릿과 비슷하지만 구현 방식이 상당히 다릅니다.)
손잡이
MC++에는 다음과 같은 두 가지 종류의 포인터가 있었습니다. __nogc
포인터는 일반적인 C++ 포인터인 반면, __gc
포인터가 작동했습니다.NET 참조 유형. 그러나 C++/CLI에서는 포인터의 유일한 유형은 일반 C++ 포인터인 반면,NET 참조 유형은 새 구문과 함께 "핸들"을 통해 액세스됩니다. ClassName^
(의 instead) ClassName*
이 새 구성은 관리되는 코드와 표준 C++ 코드가 혼합되어 있을 때 특히 유용합니다. 이 구성은 아래에 있는 개체를 명확하게 합니다.NET 자동 가비지 컬렉션 및 프로그래머가 명시적으로 파괴해야 하는 객체.
참조 추적
C++/CLI의 추적 기준은 기준별 통과 변수의 핸들입니다. 사용하는 것과 개념이 비슷합니다. *&
표준 C++에서 (포인터에 대한 참조) 및 (함수 선언에서)는 다음과 같습니다. ref
C#의 유형에 적용되는 키워드, 또는 ByRef
Visual Basic에서NET. C++/CLI는 다음을 사용합니다. ^%
핸들에 대한 추적 참조를 나타내는 구문입니다.
다음 코드는 추적 참조의 사용 예를 보여줍니다. 추적 참조를 일반 핸들 변수로 대체하면 결과적으로 10개의 초기화되지 않은 문자열 핸들이 남게 되는데, 이는 참조가 아닌 값으로 전달되기 때문에 배열에서 문자열 핸들의 복사본만 설정되기 때문입니다.
인트의 주된() { 배열한<끈^> ^arr = gcnew 배열한<끈^>(10); 인트의 i = 0; 위해서 각각(끈^% s 안에 arr) { s = i++.ToString(); } 돌아가다 0; }
C#에서는 불법이므로 허용되지 않습니다. foreach
참조를 기준으로 값을 전달하는 루프입니다. 따라서 해결책이 필요합니다.
최종 변수 및 자동 변수
C++/CLI의 또 다른 변화는 finalizer 구문의 도입입니다. !ClassName()
, 쓰레기 수거 루틴의 일부로 실행되는 비결정론적 디스트럭터의 특별한 유형입니다. C++ 디스트럭터 구문 ~ClassName()
또한 관리되는 개체에 대해서도 존재하며, 결정론적 파괴(즉, 사용자 코드에 의해 호출될 수 있는 파괴자)의 "전통적" C++ 의미론을 더 잘 반영합니다. delete
).
생으로.NET 패러다임, 비결정적 파괴 모델이 보호 대상을 재정의함 Finalize
근법 Object
클래스, 결정론적 모델은 다음을 통해 구현됩니다. IDisposable
인터페이스 방식 Dispose
(C++/CLI 컴파일러가 디스트럭터를 로 바꿉니다). C# 또는 VB의 개체입니다.Dispose 메서드를 재정의하는 NET 코드는 C++/CLI에서 수동으로 폐기할 수 있습니다. delete
처럼.C++/CLI의 NET 클래스는 가능합니다.
// C++/CLI 심판을 보다 학급 마이 클래스 { 일반의: 마이 클래스(); // 시공자 ~마이 클래스(); // (deterministic) destructor(ID로 구현됨).폐기() 보호된: !마이 클래스(); // Finalizer(비결정적 파괴자)(Final()로 구현됨) 일반의: 정적인 공허한 시험() { 마이 클래스 자동의; // 핸들도, 초기화도 없습니다. 컴파일러는 여기서 computer를 호출합니다. 마이 클래스 ^사용자 = gcnew 마이 클래스(); 지우다 사용자; // 컴파일러는 자동이 범위를 벗어날 때 자동의 디스트럭터를 호출합니다. } };
작업자오버로드
작업자 과부하는 표준 C++와 유사하게 작동합니다. *마다 ^가 되고 &마다 %가 되지만 다음과 같은 중요한 덧셈을 제외한 나머지 구문은 변경되지 않습니다.NET 클래스, 운영자 과부하는 클래스 자체뿐만 아니라 해당 클래스에 대한 참조도 가능합니다. 이 기능은 에서 예상되는 연산자 과부하에 대한 의미론을 참조 클래스에 제공하기 위해 필요합니다.NET ref classes. (반대로, 이것은 에 대해서도 의미합니다.NET 프레임워크 참조, 참조 연산자 오버로딩은 종종 C++/CLI에서 암묵적으로 구현됩니다.)
예를 들어 연산자 ==를 통해 두 개의 서로 다른 String 참조(String^)를 비교하면 두 문자열이 동일할 때마다 true가 됩니다. 그러나 작업자의 과부하는 정적입니다. 따라서 Object^에 캐스팅하면 오버로드 시맨틱스가 제거됩니다.
//참조 연산자 과부하 effects 끈 ^s1 = "abc"; 끈 ^s2 = "ab" + 다.; 물건 ^o1 = s1; 물건 ^o2 = s2; s1 == s2; // 참된 o1 == o2; // 거짓의
상호운용성
C++/CLI를 사용하면 C++ 프로그램이 C# DLL에서 C# 프로그램을 소비할 수 있습니다.[2] 여기서 #using 키워드는 DLL이 컴파일 메타데이터를 위해 위치한 컴파일러를 보여줍니다. 이 간단한 예에서는 데이터를 다중화할 필요가 없습니다.
# "stdafx"ㅎ" 사용. 네임스페이스 시스템.; #사용...MyCS.dll" 인트의 주된(배열한<시스템.::끈 ^> ^아그르그르그르그르그르그르그르그르그.) { 두 배의 x = 마이씨에스::클래스1::더하다(40.1, 1.9); 돌아가다 0; }
MyCS.dll의 C# 소스 코드 내용입니다.
네임스페이스 마이씨에스; 일반의 학급 클래스1 { 일반의 정적인 두 배의 더하다(두 배의 a, 두 배의 b) { 돌아가다 a + b; } }
이 예제에서는 C++ 문자열에서 C#에서 호출 가능한 문자열로 문자열을 마셜링한 다음 다시 C++ 문자열로 되돌리는 방법을 보여 줍니다. 문자열 다중화는 문자열 내용을 다른 환경에서 사용할 수 있는 양식으로 복사합니다.
# <끈> # <아이오스트림> # <msclr\marshal_cppstd.h> # "stdafx"ㅎ" 사용. 네임스페이스 시스템.; #사용...MyCS.dll" 인트의 주된() { std::끈의 s = "나는 고양이"; 시스템.::끈^ clrString = msclr::인터롭의::마셜_로서<시스템.::끈^>(s); // C#에서 사용 가능한 문자열 시스템.::끈^ t = 마이씨에스::클래스1::과정(clrString); // C# 함수 호출 std::끈의 cppString = msclr::인터롭의::마셜_로서<std::끈의>(t); // C++에서 사용 가능한 문자열 std::꾸트 << "안녕하세요, C++/C# 인터롭!" << std::끝을 맺다; std::꾸트 << cppString << std::끝을 맺다; 돌아가다 0; }
C# 코드는 C++ 인식 방식이 아닙니다.
네임스페이스 마이씨에스; 일반의 학급 클래스1 { 일반의 정적인 끈의 과정(끈의 a) { 돌아가다 a.교체하다("고양이", "개") + " 꼬리로"; } }
C++/C# 상호 운용성은 C++를 통해 의 전체 세계에 대한 단순화된 액세스를 가능하게 합니다.NET 기능.
C++/CX
WinRT를 대상으로 하는 C++/CX는 완전히 관리되지 않는 코드를 생성하지만, COM "objects"와 유사한 WinRT의 참조 카운트된 구성 요소에 대한 ref 및 ^ 구문을 차용합니다.[3]
참고문헌
- ^ "ECMA-372". ecma-international.org. Ecma International. December 2005. Archived from the original on 10 August 2008.
- ^ C++ Interop 사용(묵시적 PInvoke)
- ^ C++/CX 디자인 내부 - Visual C++ 팀 블로그 - 사이트 홈 - MSDN 블로그
더보기
- Sutter, Herb (23 November 2003). "C++/CLI keywords: Under the hood". Herb Sutter's Blog. Microsoft. Archived from the original on 9 November 2007.
- Sutter, Herb (24 February 2006). "A Design Rationale for C++/CLI" (PDF). Self-published.
- Stroustrup, Bjarne (23 July 2021). "What do you think of C++/CLI?". Bjarne Stroustrup's FAQ. Self-published.
- Lippman, Stanley. "Pure C++: Hello, C++/CLI". MSDN Magazine. Microsoft. 21 (3). Archived from the original on 5 February 2008.
- Lippman, Stanley (5 August 2004). "Why C++/CLI Supports both Templates for CLI Types and the CLI Generic Mechanism". Stan Lippman's BLog. Microsoft. Archived from the original on 7 October 2007.