[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