2013-07-11 5 views
5

C#WPアプリケーションで使用するWP C++ランタイムコンポーネントがあります。 C++ランタイムコンポーネントでC#およびC++/CXオブジェクトはどのように関連していますか?

、Iは、C#アプリケーションで

public interface class ICallback 
    { 
    public: 
     virtual void DoSomething(); 
    }; 

public ref class WindowsPhoneRuntimeComponent sealed 
    { 
    public: 
     WindowsPhoneRuntimeComponent(); 
     void SetCallback(ICallback ^callback); 
     IMap<Platform::String^, Platform::Object^>^ CreateDictionary(); 

    }; 

を持って、私はICallbackを実装 CallbackImpを有します。それから私は、私は次の質問のオブジェクトを管理している

  1. CBCOMを持って

    CallbackImp cb = new CallbackImp(); 
    WindowsPhoneRuntimeComponent com = new WindowsPhoneRuntimeComponent(); 
    
    // Set callback 
    com.SetCallback(cb); 
    
    // Get dictionary 
    IDictionary<string, object> dict = com.CreateDictionary(); 
    

    を行います。 C++/CXオブジェクトはどこにありますか?私は を聞いたcbcomいくつかのC++/CXオブジェクト(ネイティブヒープ上には にあります)を指摘していますか?

  2. CBCOMはC++/CXはその後解放 オブジェクトされているか、.NET GCによって解放されている場合は?
  3. 私はランタイム・コンポーネントにCBを渡し、CBは またはネイティブヒープを管理するために属しているのでしょうか?
  4. dictはどこですか?誰がそれを解放するでしょうか?

答えて

5

何も関係はありません。 C++/CXは純粋なアンマネージド言語拡張であり、WinRT型との相互運用が容易になるように設計されています。フードの下で実際にCOMタイプです。 は、管理対象のC++/CLI言語であるによく似ています。主に同じ問題を解決するために設計されているため、アンマネージタイプのinteropを簡単に作成できるからです。

C#コードでも同様のことが起こります。目に見えないほど、C#コンポーネントがマネージ型をアンマネージWinRT型として公開しています。 CLRに組み込まれた言語プロジェクションを利用します。 CLRに組み込まれている既存のCOM相互運用機能を利用します。例えば、C#クラスで封印されていることを宣言する必要があります。これは、COMが実装の継承ではなく継承をサポートしているためです。また、DateTimeの代わりにDateTimeOffsetを使用するなど、言語投影の副作用だけでDateTimeOffsetをマッピングするなど、さまざまな情報が得られます。 Etcetera。

だからあなたの質問に対処:

  1. 何のC++/CXオブジェクトがここにはありません、彼らは、COMサーバーの実装の詳細です。 WinRTオブジェクトを作成するための基礎となる低レベルのAPIはRoCreateInstance()です。これはCOM CoCreateInstance()関数と同じです。クラスファクトリを使用してオブジェクトを作成します。オブジェクトはサーバーによって所有され、通常のCOMインターフェイスポインタを超えて他のコードにはまったく公開されません。
  2. メモリはCOM、したがってWinRTで参照カウントによって管理されます。 IUnknown :: AddRef()は参照を追加し、IUnknown :: Release()は参照を解放します。最後のReleaseコールでカウントが0になると、サーバはオブジェクトを破棄します。AddRef()呼び出しは、C++/CX参照が自動的に生成され、C++/CX参照が有効範囲外になったときにコンパイラによって自動的に生成されます。 COMコードで使用するCComPtrおよび_com_ptr_tラッパークラスとまったく同じ動作ですが、スマートポインターを自分で作成する代わりに、コンパイラーが処理する点が異なります。これにより、CCWが保持する管理対象オブジェクト参照が削除されるという追加の詳細が得られます。最終的にGCがC#オブジェクトのガベージコレクションを可能にします。
  3. cbオブジェクトがGCヒープ上に存在します。上記のように、COMはインターフェイスポインタのみを公開しますが、WinRTはオブジェクトが実際に存在する場所に完全に無関心です。クラスファクトリとIUnknownメソッドは、私はC#で新しいWindowsPhoneRuntimeComponent()を呼び出すと、詳細
  4. 同じ
+0

1. 3として、WindowsPhoneRuntimeComponentのコンストラクタは、次に呼び出されたことを隠すため、C++/CXがなければなりませんネイティブヒープのどこかに存在するオブジェクト? また、ランタイムコンポーネントプロジェクトで新規に参照すると、その新しく作成されたオブジェクトのアドレスがわかります。「オブジェクトはサーバーによって所有されています」という意味はどうですか? 2.「あなたのC++/CX参照が範囲外になりますか? "私は個人的には、cbとcomが管理されたヒープにあると考えているので、GCはいつそれらをリリースするかを決めるでしょう。これはC++/CXオブジェクトもリリースされます。 – onmyway133

+0

あなた自身の精神モデルを働くしかしそれは非常に正確なものではありません。 WinRTの種類を理解するためには、COMを理解する必要があります。それと幸運。 –

+0

http://social.msdn.microsoft.com/Forums/windowsapps/en-US/d41b7773-d85e-4d1c-97a1-2c8579da62c2/how-does-memory-allocation-work-with-native-winrt-typesによるとC#またはVBの呼び出し元がGCコレクションを介して投影された.NETオブジェクトを解放するたびに、それらのオブジェクトは自動的に解放されます。参照カウントが0になると、デストラクタ(もしあれば)が呼び出され、メモリは " – onmyway133