C++/CLI ラッピング入門
今回はオブジェクトラッピングの基礎、
アンマネージリソースの生成と破棄についてです。
———————————————————————–
マネージドオブジェクトは、アンマネージドオブジェクトを
直接メンバ変数に持つことができません。
アンマネージドオブジェクトのポインタをメンバ変数に持つことは可能なため、
マネージドオブジェクトはポインタを通してアンマネージドオブジェクトを扱うことになります。
アンマネージドリソースをラップしたオブジェクトは、
呼び出し側(C#,VB.NET等)からは普通のマネージドオブジェクトに見えてほしいので、
アンマネージドオブジェクトへのポインタはアクセス指定子をinternalにして、
アセンブリの外からは見えないようにします。
ネイティブオブジェクトの管理で最も簡単な方法は、
コンストラクタでオブジェクトを生成(new)し、
デストラクタ及び、ファイナライザでオブジェクトを破棄(delete)する方法です。
デストラクタはdeleteやDispose()などを用いて、
マネージドオブジェクトを明示的に破棄した際に呼び出され、
ファイナライザは、明示的に破棄しないまま
ガベージコレクタによりオブジェクトが解放される際に呼び出されます。
デストラクタが呼び出された場合ファイナライザは呼び出されません。
デストラクタでは、オブジェクトが所持しているマネージドリソース、
アンマネージリソース両方を開放する必要があります。
ファイナライザでは、マネージドリソースは
すでにガベージコレクタにより解放されている可能性があり、
またそうでなくてもいずれ、解放されるため、
アンマネージリソースのみを開放します。
デストラクタからは、ファイナライザを普通の関数として呼び出すこともできるので、
デストラクタでは、マネージドオブジェクトを開放してから、ファイナライザを呼び出し、
ファイナライザでアンマネージリソースを解放するという書き方が推奨されます。
//----------------------------------------------------------
// ヘッダファイル ManagedClass.h
//アンマネージドクラス
class UnmanagedClass
{
...
};
//参照型、マネージドクラス
public ref class ManagedClass
{
internal:
// アンマネージドオブジェクトへのポインタ
// ライブラリの外からは見れないようにinternalにする
UnmanagedClass* pData;
public:
//コンストラクタ
ManagedClass() ;
//デストラクタ
~ManagedClass() ;
//ファイナライザ
!ManagedClass() ;
};
//----------------------------------------------------------
// ソースファイル ManagedClass.cpp
#include "ManagedClass.h"
ManagedClass::ManagedClass()
{
// アンマネージドオブジェクトの生成
this->pData = new UnmanagedClass();
}
//デストラクタ
ManagedClass::~ManagedClass()
{
// ここでマネージドオブジェクトを開放
this->!ManagedClass();
}
// ファイナライザ
ManagedClass::!ManagedClass()
{
// アンマネージドオブジェクトの開放
delete this->pData;
}
//----------------------------------------------------------
次回は関数のラップについて紹介する予定