2020년 8월 27일 목요일

C++/CIL 로 C#에서 쓰기 - Ref, Handle Object Operator

 


CLI 는 Managed Language 를 지원한다.

C++ 의 포인터, 동적할당 이건 UnManaged Language 의 특징이다.

Managed Class, Struct 를 사용하면 C# 등의 환경에서 기존의 C# 의 클래스와 거의 똑같이 쓸 수 있는 장점이 있다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
using namespace System;
using namespace System::Collections;
 
namespace ClassLibrary1 {
 
    public ref struct AAA {
        AAA(int a, int b) : a(a), b(b) {}
        AAA(const AAA% rs) { a = rs.a; b = rs.b; }
 
        int a;
        int b;
    };
 
    public ref class Class1
    {
    public:
        Class1() {
 
            for (int i = 0; i < 10; i++)
                aaas.Add(gcnew AAA(i, 10 * i));
        };
    private:
        ArrayList aaas;
    }
}
cs


Managed Class, Struct

CLI 을 쓰기 위해선 ref 자료형(ref struct, ref class) 를 사용해야한다.

gcnew 를 통해서 생성한다. 

소멸은 delete 을 통해서 하지만 소멸자만 호출될 뿐 메모리 할당 해제는 gc 가 알아서 한다.

gc 에서 해제될 때 finalize 가 호출되며 소멸자가 ~쓰듯 !를 앞에 붙여서 정의한다.

*, 대신 Handle 이라고 불리는 ^ 를 사용하고, % 대신 % 를 사용한다.


 스택영역에 인스턴스를 만드듯 gcnew 를 안쓸 수도 있지만 이 경우에도 메모리는 gc 가 처리한다. 이는 컴파일러 나중에 gcnew 를 붙이고 스택에서 나올 때 delete 를 넣어주기 때문이다.


 ref class 와 달리 class 앞에 value 를 넣는다던가 (public) enum class 는 서로 값이 복사가 된다. 단 int 같은 기본 리터럴만 들어갈 수 있다. 복사 생성자를 쓸 수 없는 managed class 의 보안으로 보면 된다. 이런 클래스는 c# 에서 구조체를 복사값으로 많이 쓰는 것과 연관지을 수 있을 것 같다.


Pointer

nullptr 은 c# 의 null 와 같은 개념으로 쓰인다.

interior_ptr 은 managed class 나 그 member 를 포인터화 하기위해서 쓰이며 % 와 비슷하다. gc 가 주소를 바꿔도 추적이 가능하다.

pin_ptr 은 managed class 를 unmanaged language 에서 쓰는동안 gc 가 변경하지 못하도록 막는 역할을 한다. nullptr 로 초기화하는 unpin 을 빨리하는 것이 좋다.


Array

배열이 필요하면 Array, ArrayList 등을 사용해야한다.

C# 의 자료구조를 쓴다면 for 문보다 c# 의 for each 문이 좋다고 한다.

managed 객체에 & 를 쓰면 객체 자체가 나오기 때문에 &array[0] 이 쓰이는 것이 특이점.

http://mag.autumn.org/Content.modf?id=20050507224044


GCRoot

Parameter Array(가변인자 가능)


기타

enum class 는 예외적으로 struct 와 똑같이 public 이 앞에 붙으면 c# 에서도 사용가능하다.



List