C++/CLIを使う理由の1つは既存のCライブラリを使うことです。このとき既存ライブラリのデータをCLRアプリでどう扱うか、という問題があります。
ref classはネイティブクラスの実体をもつことはできませんが、ポインタなら持つことができます。ただしref classはその開放方法が様々なので、そのポインタをどうやって破棄するのかを考えておかなければなりません。
#include <string.h> #include <stdlib.h> using namespace System; ref class REFCLASS { void clearp() { if (p) { free((void*)p); p = NULL; } } public: char* p; ~REFCLASS() { clearp(); } !REFCLASS() { clearp(); } }; int main(array<System::String ^> ^args) { { REFCLASS c; c.p = strdup("AAA"); Console::WriteLine(gcnew String(c.p)); REFCLASS^ hc = gcnew REFCLASS; hc->p = strdup("BBB"); Console::WriteLine(gcnew String(hc->p)); } return 0; }
gcrootを使うと、ネイティブクラスの中にハンドルを持つことができます。
#include <gcroot.h> using namespace System; class NativeClass { public: gcroot<String^> clrstring; }; int main(array<System::String ^> ^args) { String^ s = L"AAA"; NativeClass n; n.clrstring = s; Console::WriteLine(n.clrstring); return 0; }
gcrootはC++クラスでメンバはvoid* handle;だけです。これはSystem::Runtime::InteropServices::GCHandle::Alloc()の戻り値をキャストしたものです。