2013-07-11 4 views
5

Ich habe eine WP C++ Runtime-Komponente, die von einer C# -WP-Anwendung verbraucht werden soll. Runtime-KomponenteWie hängen C# - und C++/CX-Objekte zusammen?

In C++, habe ich

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(); 

    }; 

In C# Anwendung, ich habe CallbackImp, die ICallback implementiert. Dann mache ich

CallbackImp cb = new CallbackImp(); 
WindowsPhoneRuntimeComponent com = new WindowsPhoneRuntimeComponent(); 

// Set callback 
com.SetCallback(cb); 

// Get dictionary 
IDictionary<string, object> dict = com.CreateDictionary(); 

Ich habe folgende Fragen

  1. cb und com werden verwaltete Objekte. Wo sind die C++/CX-Objekte? Ich habe gehört, dass cb und com zeigen Sie auf einige C++/CX-Objekte (die auf native Heap residieren), richtig?
  2. Wenn cb und com von .NET GC freigegeben werden, sind, wie C++/CX dann released Objekte?
  3. Als ich cb auf die Runtime-Komponente übergeben, wird cb gehört oder native Heap verwaltet?
  4. Wo befindet sich dict? Wer wird es veröffentlichen?

Antwort

5

Es gibt überhaupt keine Beziehung. C++/CX ist eine reine, nicht verwaltete Spracherweiterung, die Interop mit WinRT-Typen einfach macht. Welches sind eigentlich COM-Typen unter der Haube. Die Syntax ähnelt der verwalteten C++/CLI-Sprache sehr, vor allem, weil sie entwickelt wurden, um das gleiche Problem zu lösen, was Interop mit unmanaged Typen einfach macht.

Ähnliches passiert auch in Ihrem C# -Code. Weitaus weniger sichtbar macht Ihre C# -Komponente den verwalteten Typ als nicht verwalteten WinRT-Typ verfügbar. Die Sprachprojektion in CLR nutzen. Dies wiederum nutzt den vorhandenen COM-Interop, der in die CLR integriert ist. Es ist nicht vollständig unsichtbar, Sie müssen zum Beispiel Ihre C# -Klasse versiegelt, eine Einschränkung, die von COM nur Unterstützung Schnittstelle Vererbung, nicht Umsetzung Vererbung. Und verschiedene andere Leckerbissen, wie DateTimeOffset anstelle von DateTime verwenden zu müssen, ein Nebeneffekt der Sprachprojektion, die nur DateTimeOffset abbildet. Und so weiter.

Adressierung So Ihre Fragen:

  1. Es sind keine C++/CX Objekte hier, sie sind eine Implementierung Detail des COM-Servers. Die zugrunde liegende Low-Level-API zum Erstellen von WinRT-Objekten ist RoCreateInstance(), dasselbe Tier wie die COM CoCreateInstance() - Funktion. Das verwendet eine Klassenfactory, um das Objekt zu erstellen. Das Objekt befindet sich im Besitz des Servers. Es wird überhaupt nicht mit anderem Code als den normalen COM-Schnittstellenzeigern verfügbar gemacht.
  2. Speicher wird in COM und damit WinRT durch Referenzzählung verwaltet. IUnknown :: AddRef() fügt einen Verweis hinzu, IUnknown :: Release() gibt einen Verweis frei. Der Server zerstört das Objekt, wenn der letzte Release-Aufruf die Anzahl auf 0 verringert.Der AddRef() -Aufruf wird automatisch generiert eine ref new oder Objektreferenzzuweisungsanweisung in Ihrem C++/CX-Code, Release() wird vom Compiler automatisch generiert, wenn Ihre C++/CX-Referenz den Gültigkeitsbereich verlässt. Genau dasselbe Verhalten wie die CComPtr- und _com_ptr_t-Wrapper-Klassen, die Sie in COM-Code verwenden würden, aber mit dem Unterschied, dass der Compiler sich darum kümmert, anstatt dass Sie selbst einen Smart Pointer erstellen müssen. Mit den zusätzlichen Details entfernt dies die Referenz des verwalteten Objekts, die von der CCW gehalten wird. was schließlich ermöglicht, dass der GC das C# -Objekt auf Müll sammelt.
  3. Das Objekt cb existiert auf dem GC-Heap. Wie oben erwähnt, stellt COM nur Schnittstellenzeiger zur Verfügung, WinRT ist völlig unabhängig davon, wo ein Objekt tatsächlich lebt. Die Klassenfactory und die IUnknown-Methoden verbergen, dass Detail
  4. Gleiche wie 3.
+0

1. Wenn ich neue WindowsPhoneRuntimeComponent() aufrufen, in C#, der Konstruktor des WindowsPhoneRuntimeComponent dann aufgerufen wird, so muss es C++/CX sein Objekt befindet sich irgendwo im nativen Heap? Auch wenn ich neu in Runtime-Komponente Projekt, kann ich die Adresse des neu erstellten Objekts sehen, was meinen Sie mit "Das Objekt gehört dem Server" 2. Was meinst du mit "wenn Ihre C++/CX-Referenz geht nicht in den Geltungsbereich "? Ich persönlich denke, dass cb und com in verwalteten Heap sind, so dass der GC entscheiden wird, wann sie veröffentlicht werden, und dies wird dazu führen, dass die C++/CX-Objekte auch freigegeben werden. – onmyway133

+0

Es ist in Ordnung, Ihr eigenes mentales Modell darüber zu machen funktioniert. Es ist jedoch nicht sehr genau. Sie müssen COM verstehen, um WinRT-Typen zu erstellen. Viel Glück damit. –

+0

Nach http://social.msdn.microsoft.com/Forums/windowsapps/en-US/d41b7773-d85e-4d1c-97a1-2c8579da62c2/how-does-memory-allocation-work-with-native-winrt-types -in-managed-code "WinRT-Typen werden auf dem systemeigenen Heap erstellt, sie werden nicht als Garbage Collection erfasst. Wie Sie bereits sagten, werden sie gezählt. Wenn ein C# - oder VB-Aufrufer ein projiziertes .NET-Objekt über eine GC-Sammlung freigibt Das zugrundeliegende RT-Objekt erhält seine ref-Zählung dekrementiert Wenn die ref-Zählung 0 erreicht, wird ihr Destruktor (falls vorhanden) aufgerufen und der Speicher wird freigegeben " – onmyway133

Verwandte Themen