[유니티/C#]GCHandle이란 무엇인가
안녕하세요. 개발자 드리머즈입니다.
GCHandle에 대해 조사해보겠습니다.
GCHandle은 찾아보니 Unity가 아닌 .NET Framework에 존재하는 구조체입니다.(System.Runtime.InteropServices에 속함)
https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.gchandle(v=vs.110).aspx
Provides a way to access a managed object from unmanaged memory.
라고 설명이 되어있습니다. 관리되지 않는 메모리부터 관리되는 객체에 접근할 방법을 제공한다?라고 하는데 이해가 잘 되지 않습니다.
https://stackoverflow.com/questions/7688287/what-exactly-is-the-contract-of-gchandle-allocobject를 읽어보면 조금 이해가 되는 것 같습니다.
GCHandle에서 GC는 Garbage Colloector의 약자인 것 같습니다.
에도 좋은 설명이 있습니다.
GCHandle.Alloc은 GC Heap에 할당된 객체를 pinning하는 것으로 오히려 GC에 부담을 줍니다. 다음의 문서에도 나오지만,
GCHandle.Alloc Method (Object) - https://msdn.microsoft.com/ko-kr/library/a95009h1(v=vs.110).aspx
GCHandle.Alloc은 native 코드에서 관리 힙의 객체를 접근해야 할 경우를 위해 만들어진 것입니다.
또 다른 좋은 설명이 있습니다.(https://blog.naver.com/indpkr/220064279914)
이 기종간의 데이터를 전달함에 있어서 가장 간편하고 빠른 방법은 공유메모리를 만들고 양쪽 시스템이 이를 접근하게 만들어주는 것입니다.
하지만 C#에서 메모리를 만드는 경우, 가비지콜렉션이 언제 발생할지 모르는 상황이 발생하기 때문에, 네이티브가 안전하게 메모리 영역에 접근하기가 쉽지 않습니다. 이를 위해 .NET이 제공하는 함수 중에 GCHandle.Alloc이라는 함수가 있습니다.
GCHandle.Alloc 함수는 C#에서 생성한 메모리를 고정시켜주는 역할을 수행하며, 이를 IntPtr로 네이티브에 전달하면 네이티브에서 이를 접근하는 것이 가능합니다.
제가 접한 GCHandle을 사용하는 코드는 아래와 같습니다.
1 2 | pixels = webcamscreen.GetPixels32(); pixelsHandle = GCHandle.Alloc(pixels, GCHandleType.Pinned); | cs |
https://msdn.microsoft.com/en-us/library/1246yz8f(v=vs.110).aspx
에 Alloc 함수에 대한 설명이 있습니다.
1 | public static GCHandle Alloc(object value, GCHandleType type) | cs |
GCHandle.Alloc()함수가 사용됐습니다. Alloc 함수는 인자를 2개 가집니다.
첫 번째 인자는 GCHandle을 사용할 객체를 넣으면 되고, 두 번째 인자는 생성할 GCHandle의 타입을 넣으면 됩니다.
GCHandle의 타입은 4개가 있는데 위의 예제에서 사용된 Pinned 속성만 간단하게 보겠습니다.
(https://msdn.microsoft.com/en-us/library/83y4ak54(v=vs.110).aspx)
GCHandle로 관리하는 객체의 주소를 고정시키는 것 같습니다. 이렇게 하면 GC의 효율성이 떨어지니 가능하면 빨리 Free 함수를 사용하라고 합니다.
GCHandle에는 AddrOfPinnedObject()라는 함수가 있습니다. 이 함수는 말 그대로 Pinned된 객체의 주소를 반환하는 함수입니다.
C#에서 만들어진 객체를 C++에서 접근할 수 있도록할 때 GCHandle.Alloc()를 사용합니다.
댓글 영역