[Kde-bindings] playground/bindings/kimono

Richard Dale Richard_Dale at tipitina.demon.co.uk
Thu Feb 8 11:17:46 UTC 2007


SVN commit 631534 by rdale:

* Added a strongReferenceMap to hold a mapping from a C++ pointer to
  a C# instance. It is used to prevent garbage collection for instances
  which are contained in another instance, such as a QObject with a
  parent, even when there are no references to the child within the C#
  Qyoto application code. When the parent finally deletes the child on 
  the C++ side, the reference is removed from the Dictionary by the 
  SmokeMarshallers.UnmapPointer() method.
* Renamed the QTDB_METHOD_MISSING debugging flag as QTDB_TRANSPARENT_PROXY

CCMAIL: kde-bindings at kde.org



 M  +8 -0      ChangeLog  
 M  +1 -1      SmokeInvocation.cs  
 M  +45 -5     SmokeMarshallers.cs  
 M  +1 -1      qyoto.h  


--- trunk/playground/bindings/kimono/ChangeLog #631533:631534
@@ -3,6 +3,14 @@
 	* Fixed bugs in the debug dump of QMetaObjects created at runtime
 	* Normalized some code layout
 	* Only QApplication and QCoreApplication destructors are now called
+	* Added a strongReferenceMap to hold a mapping from a C++ pointer to
+	  a C# instance. It is used to prevent garbage collection for instances
+	  which are contained in another instance, such as a QObject with a
+	  parent, even when there are no references to the child within the C#
+	  Qyoto application code. When the parent finally deletes the child on 
+	  the C++ side, the reference is removed from the Dictionary by the 
+	  SmokeMarshallers.UnmapPointer() method.
+	* Renamed the QTDB_METHOD_MISSING debugging flag as QTDB_TRANSPARENT_PROXY
 
 2007-02-07  Richard Dale  <rdale at foton.es>
 
--- trunk/playground/bindings/kimono/SmokeInvocation.cs #631533:631534
@@ -349,7 +349,7 @@
 		public override IMessage Invoke(IMessage message) {
 			IMethodCallMessage callMessage = (IMethodCallMessage) message;
 //#if DEBUG
-			if ((Debug.DebugChannel() & QtDebugChannel.QTDB_METHOD_MISSING) != 0) {
+			if ((Debug.DebugChannel() & QtDebugChannel.QTDB_TRANSPARENT_PROXY) != 0) {
 				Console.WriteLine(	"ENTER Invoke() MethodName: {0}.{1} Type: {2} ArgCount: {3}", 
 									_className,
 									callMessage.MethodName, 
--- trunk/playground/bindings/kimono/SmokeMarshallers.cs #631533:631534
@@ -199,6 +199,15 @@
 		}
 
 		// The key is an IntPtr corresponding to the address of the C++ instance,
+		// and the value is a the C# instance. This is used to prevent garbage
+		// collection for instances which are contained inside, and owned by
+		// other instances. For instance, a QObject can have a parent which will
+		// delete the child when it is deleted. This Dictionary will prevent the
+		// child from being GCd even if there are no references to it in the Qyoto
+		// application code.
+		static private Dictionary<IntPtr, object> strongReferenceMap = new Dictionary<IntPtr, object>();
+
+		// The key is an IntPtr corresponding to the address of the C++ instance,
 		// and the value is a WeakReference to the C# instance.
 		static private Dictionary<IntPtr, WeakReference> pointerMap = new Dictionary<IntPtr, WeakReference>();
 
@@ -210,25 +219,56 @@
 		
 		public static void UnmapPointer(IntPtr ptr) {
 			pointerMap.Remove(ptr);
+			if (!strongReferenceMap.ContainsKey(ptr)) {
+#if DEBUG
+				if ((Debug.DebugChannel() & QtDebugChannel.QTDB_GC) != 0) {
+					object ref;
+					if (strongReferenceMap.TryGetValue(ptr, out ref)) {
+						Console.WriteLine("UnmapPointer() Removing strong reference {0} to ptr: {1}", ref, ptr);
+					}
+				}
+#endif
+				strongReferenceMap.Remove(ptr);
+			}
 		}
 		
 		public static IntPtr GetPointerObject(IntPtr ptr) {
-//			Console.WriteLine("ENTER GetPointerObject() ptr: {0}", ptr);
+#if DEBUG
+			if ((Debug.DebugChannel() & QtDebugChannel.QTDB_GC) != 0) {
+				Console.WriteLine("ENTER GetPointerObject() ptr: {0}", ptr);
+			}
+#endif
 			WeakReference weakRef;
 			if (!pointerMap.TryGetValue(ptr, out weakRef)) {
-//				Console.WriteLine("GetPointerObject() pointerMap[ptr] == null");
+#if DEBUG
+				if ((Debug.DebugChannel() & QtDebugChannel.QTDB_GC) != 0) {
+					Console.WriteLine("GetPointerObject() pointerMap[ptr] == null");
+				}
+#endif
 				return (IntPtr) 0;
 			}
 
 			if (weakRef == null) {
-//				Console.WriteLine("GetPointerObject() weakRef zero");
+#if DEBUG
+				if ((Debug.DebugChannel() & QtDebugChannel.QTDB_GC) != 0) {
+					Console.WriteLine("GetPointerObject() weakRef zero");
+				}
+#endif
 				return (IntPtr) 0;
 			} else if (weakRef.IsAlive) {
-//				Console.WriteLine("GetPointerObject() weakRef.IsAlive");
+#if DEBUG
+				if ((Debug.DebugChannel() & QtDebugChannel.QTDB_GC) != 0) {
+					Console.WriteLine("GetPointerObject() weakRef.IsAlive");
+				}
+#endif
 				GCHandle instanceHandle = GCHandle.Alloc(weakRef.Target);
 				return (IntPtr) instanceHandle;
 			} else {
-//				Console.WriteLine("GetPointerObject() weakRef dead");
+#if DEBUG
+				if ((Debug.DebugChannel() & QtDebugChannel.QTDB_GC) != 0) {
+					Console.WriteLine("GetPointerObject() weakRef dead");
+				}
+#endif
 				return (IntPtr) 0;
 			}
 		}
--- trunk/playground/bindings/kimono/qyoto.h #631533:631534
@@ -46,7 +46,7 @@
 enum QtDebugChannel {
     qtdb_none = 0x00,
     qtdb_ambiguous = 0x01,
-    qtdb_method_missing = 0x02,
+    qtdb_transparent_proxy = 0x02,
     qtdb_calls = 0x04,
     qtdb_gc = 0x08,
     qtdb_virtual = 0x10,



More information about the Kde-bindings mailing list