GetWrapper()
一部のC++/ CLIコードには、独自のマネージド.NETラッパーオブジェクトを作成するためのファクトリメソッドを持つネイティブクラスがあります。内部的には、GCHandleを介したラッパーへの弱参照を保持しています。がGetWrapper()
呼び出されると、GCHandleがチェックされ、既存のラッパーへのハンドルが返されるか、(古いラッパーオブジェクトがガベージコレクターによって破棄されたためにオブジェクトを指していない場合)、新しいラッパーが作成されます。戻ってきた。
// .h
class NativeClass
{
public:
WrapperClass^ GetWrapper();
private:
WrapperClass^ GetNewWrapper();
GCHandle m_wrapperGCHandle;
};
// .cpp
WrapperClass^ NativeClass::GetWrapper()
{
if(m_wrapperGCHandle.IsAllocated)
{
try
{
WrapperClass^ wrapper = nullptr;
wrapper = dynamic_cast<WrapperClass^>(wrapperGCHandle.Target);
if(wrapper == nullptr)
{
return GetNewWrapper();
}
else
{
return wrapper;
}
}
catch(System::InvalidOperationException^)
{
return GetNewWrapper();
}
else
{
return GetNewWrapper();
}
}
WrapperClass^ NativeClass::GetNewWrapper()
{
WrapperClass^ wrapper = gcnew WrapperClass(/*some args*/);
m_wrapperGCHandle = GCHandle::Alloc(wrapper, GCHandleType::Weak);
}
奇妙なことに、ラッパーがガベージコレクションされた場合でも、m_wrapperGCHandle.IsAllocated
常にtrueが返されます。MSDNは、「弱いハンドルを使用してGCHandleがまだ使用可能かどうかを判断するときに、このプロパティを使用する」と指示しています。しかし、それは常に真実です。使用できない場合、ターゲットは代わりにnullptrです。
何かが足りないのですか、それともMSDNが間違っていますか?