nullptr
C/C++에서 포인터를 초기화 할 때 ‘NULL’을 사용합니다. 그러나 VC++ 10에는 C++0x에서는 포인터를 초기화 할 때 NULL 대신 새로 생긴 ‘nullptr’을 사용할 수 있게 되었습니다.
C++/CLI는 이전부터 nullptr이 있었습니다.
C++/CLI에서는 ref 클래스의 핸들을 초기화 할 때는 nullptr을 사용합니다.
C++/CLI, C++0x의 nullptr은 C/C++ 처럼 ‘0’이 아니라는 것을 잘 기억하시기 바랍니다.
interior_ptr
interior_ptr은 관리 힙(managed heap. 즉 GC겠죠) 상의 value type나 기본형을 가리키는 포인터라고 할 수 있습니다. interior_ptr는 value type나 기본형을 비관리 코드의 포인터처럼 사용하고 싶을 때 사용하면 좋습니다.
< 코드 1. >
ref class REFClass
{
public:
int nValue;
};
void SetValue( int* nValue )
{
*nValue = 100;
}
int main()
{
REFClass^ refClass = gcnew REFClass;
SetValue( &refClass->nValue ); // 에러
}
위 코드를 빌드 해 보면 SetValue( &refClass->nValue ); 에서 빌드 에러가 발생합니다. 매니지드 힙에 있는 것은 그 위치가 변하므로 비 관리 코드의 포인터를 넘길 수가 없습니다. 그럼 <코드 1>를 정상적으로 빌드 하기 위해서 interior_ptr를 사용해 보겠습니다.
< 코드 2. >
ref class REFClass
{
public:
int nValue;
};
void SetValue( interior_ptr<int> nValue )
{
*nValue = 100;
}
int main()
{
REFClass^ refClass = gcnew REFClass;
SetValue( &refClass->nValue );
}
<코드 2>의 SetValue의 파라미터로 비관리 코드의 참조나 포인터를 넘길 수도 있습니다.
< 코드 3. >
#include <iostream>
void SetValue( interior_ptr<int> nValue )
{
*nValue = 100;
}
int main()
{
int nValue = 50;
SetValue( &nValue );
std::cout << nValue << std::endl;
getchar();
return 0;
}
그리고 interior_ptr에 대신 C++/CLI의 참조(‘%’)를 사용하는 방법도 있습니다.
pin_ptr
pin_ptr은 관리 힙 상의 value type나 기본형을 비관리 코드에서 포인터로 사용하고 싶을 때 사용하는 기능입니다. 가장 필요한 경우가 C++/CLI에서 기존의 비관리 코드로 만들어 놓은 라이브러리를 사용할 때입니다.
< 코드 4. >
ref class REFClass
{
public:
int nValue;
};
void SetValue( int* pValue )
{
*pValue = 100;
}
int main()
{
REFClass^ refClass = gcnew REFClass;
pin_ptr<int> pValue = &refClass->nValue;
SetValue( pValue );
pValue = nullptr;
}
pin_ptr에 메모리 주소를 할당하는 것을 ‘pin’이라고 부르고 사용이 끝난 후 nullptr로 초기화 하는 것을 ‘unpin’ 이라고 부릅니다. pin_ptr 사용이 끝난 후 가능한 빨리 unpin 해주는 것이 좋습니다.
interior_ptr과 pin_ptr의 차이점
interipor_ptr과 pin_ptr은 둘 다 관리 힙 상의 value type이나 기본형을 가리키는 포인터로 사용되지만 interior_ptr은 관리 힙 상에서 인스턴스가 이동하여도 올바르게 추적할 수 있는 포인터로 런타임의 지배하에 있습니다(즉 인스턴스가 관리 힙 상에서 이동하여도 괜찮습니다).
pin_ptr은 관리 힙 상의 value type을 비관리 코드에서 사용하고 싶을 때 사용합니다. 당연히 이 때는 관리 힙에 있는 인스턴스가 이동하면 안되므로 인스턴스의 이동을 금지합니다.
interipor_ptr과 pin_ptr의 같은 점 : 포인터처럼 사용할 수 있다.
interipor_ptr과 pin_ptr 다른 점 : interipor_ptr은 관리 코드 상에서 포인터로 사용하고, pin_ptr는 비관리 코드에 포인터로 넘길 때 사용합니다.
interipor_ptr과 pin_ptr을 공부했으니 다음에는 C++/CLI에서 비관리 C++과 혼합해서 사용할 때 어떻게 해야 하는지 설명하겠습니다.
참고
http://cppcli.shacknet.nu/cli:interior_ptr
http://cppcli.shacknet.nu/cli:pin_ptr
http://cppcli.shacknet.nu/cli:interior_ptr%E3%81%A8pin_ptr%E3%81%AE%E9%81%95%E3%81%84
'C++/CLI' 카테고리의 다른 글
[Step. 06-1] 관리코드의 문자열과 비관리코드의 문자열 변환 (0) | 2010.07.16 |
---|---|
[Step. 05] 관리 코드의 array를 비관리 코드에 포인터로 전달 (0) | 2010.07.09 |
[step.03] 배열 (1) | 2010.06.18 |
[Step.02-2] 클래스(class), 핸들(^), 그리고 구조체(struct) (5) | 2010.06.11 |
[Step 02-1] 클래스(class), 핸들(^), 그리고 구조체(struct) (1) | 2010.06.04 |