[Kde-bindings] playground/bindings/kimono
Richard Dale
Richard_Dale at tipitina.demon.co.uk
Thu Feb 8 18:07:04 UTC 2007
SVN commit 631668 by rdale:
* Added a first attempt at setting up the strongReferenceMap and calling
destructors. A boolean function CreateStrongReference() checks whether
or not a strong reference is needed when a new instance has been
constructed. Another function is needed to checked whether the C++
instance still has a parent or container, and not delete if it has.
* Currently apps crash on exit, but the Qyoto.DeleteQApp()
hack shouldn't be need anymore once destructors are working.
CCMAIL: kde-bindings at kde.org
M +11 -0 ChangeLog
M +16 -7 SmokeInvocation.cs
M +29 -9 SmokeMarshallers.cs
M +42 -0 handlers.cpp
M +8 -4 qyoto.cpp
M +2 -0 qyoto.h
--- trunk/playground/bindings/kimono/ChangeLog #631667:631668
@@ -1,3 +1,14 @@
+2007-02-08 Richard Dale <rdale at foton.es>
+
+ * Added a first attempt at setting up the strongReferenceMap and calling
+ destructors. A boolean function CreateStrongReference() checks whether
+ or not a strong reference is needed when a new instance has been
+ constructed. Another function is needed to checked whether the C++
+ instance still has a parent or container, and not delete if it has.
+
+ * Currently apps crash on exit, but the Qyoto.DeleteQApp()
+ hack shouldn't be need anymore once destructors are working.
+
2007-02-08 Arno Rehn <arno at arnorehn.de>
* Fixed names of flags in Qyoto.cs
--- trunk/playground/bindings/kimono/SmokeInvocation.cs #631667:631668
@@ -374,15 +374,24 @@
IMethodReturnMessage returnMessage = (IMethodReturnMessage) message;
- // Ignore destructors for now until a way of coordinating C# GC
- // with C++ deletions has been implemented
- if ( !((SmokeMethod) smokeMethod[0]).MungedName.StartsWith("~")
- || (_className == "QApplication" && ((SmokeMethod) smokeMethod[0]).MungedName == "~QApplication")
- || (_className == "QCoreApplication" && ((SmokeMethod) smokeMethod[0]).MungedName == "~QCoreApplication") )
+ // Ignore destructors where the destructor method isn't the actual class
+ // of the instance
+ if ( ( ((SmokeMethod) smokeMethod[0]).MungedName.StartsWith("~")
+ && (("~" + _className) != ((SmokeMethod) smokeMethod[0]).MungedName) )
+ || ((SmokeMethod) smokeMethod[0]).MungedName == "~QMetaObject" )
{
+#if DEBUG
+ if ((Debug.DebugChannel() & QtDebugChannel.QTDB_TRANSPARENT_PROXY) != 0) {
+ Console.WriteLine( "SKIPPING Invoke() MethodName: {0}.{1} Type: {2} ArgCount: {3}",
+ _className,
+ callMessage.MethodName,
+ callMessage.TypeName,
+ callMessage.ArgCount.ToString() );
+ }
+#endif
+ return returnMessage;
+ } else {
;
- } else {
- return returnMessage;
}
if (methodId == -1) {
--- trunk/playground/bindings/kimono/SmokeMarshallers.cs #631667:631668
@@ -1,3 +1,5 @@
+#define DEBUG
+
namespace Qyoto {
using System;
using System.Collections;
@@ -62,7 +64,7 @@
public static extern void InstallSetSmokeObject(SetIntPtr callback);
[DllImport("libqyoto", CharSet=CharSet.Ansi)]
- public static extern void InstallMapPointer(SetIntPtr callback);
+ public static extern void InstallMapPointer(MapPointerFn callback);
[DllImport("libqyoto", CharSet=CharSet.Ansi)]
public static extern void InstallUnmapPointer(FromIntPtr callback);
@@ -142,6 +144,7 @@
public delegate IntPtr GetIntPtr(IntPtr instance);
public delegate void SetIntPtr(IntPtr instance, IntPtr ptr);
public delegate void FromIntPtr(IntPtr ptr);
+ public delegate void MapPointerFn(IntPtr instance, IntPtr ptr, bool createStrongReference);
public delegate IntPtr CreateInstanceFn(string className);
public delegate void InvokeCustomSlotFn(IntPtr obj, string slot, IntPtr stack, IntPtr ret);
public delegate bool IsSmokeClassFn(IntPtr obj);
@@ -211,10 +214,23 @@
// and the value is a WeakReference to the C# instance.
static private Dictionary<IntPtr, WeakReference> pointerMap = new Dictionary<IntPtr, WeakReference>();
- public static void MapPointer(IntPtr ptr, IntPtr instancePtr) {
+ public static void MapPointer(IntPtr ptr, IntPtr instancePtr, bool createStrongReference) {
Object instance = ((GCHandle) instancePtr).Target;
WeakReference weakRef = new WeakReference(instance);
pointerMap[ptr] = weakRef;
+#if DEBUG
+ if ((Debug.DebugChannel() & QtDebugChannel.QTDB_GC) != 0) {
+ Console.WriteLine("MapPointer() Creating weak reference {0} to ptr: {1}", instance, ptr);
+ }
+#endif
+ if (createStrongReference) {
+ strongReferenceMap[ptr] = instance;
+#if DEBUG
+ if ((Debug.DebugChannel() & QtDebugChannel.QTDB_GC) != 0) {
+ Console.WriteLine("MapPointer() Creating strong reference {0} to ptr: {1}", instance, ptr);
+ }
+#endif
+ }
}
public static void UnmapPointer(IntPtr ptr) {
@@ -222,9 +238,9 @@
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);
+ object reference;
+ if (strongReferenceMap.TryGetValue(ptr, out reference)) {
+ Console.WriteLine("UnmapPointer() Removing strong reference {0} to ptr: {1}", reference, ptr);
}
}
#endif
@@ -286,7 +302,9 @@
public static IntPtr CreateInstance(string className) {
Type klass = Type.GetType(className);
#if DEBUG
- Console.WriteLine("ENTER CreateInstance className => {0}, {1}", className, klass);
+ if ((Debug.DebugChannel() & QtDebugChannel.QTDB_GC) != 0) {
+ Console.WriteLine("ENTER CreateInstance className => {0}, {1}", className, klass);
+ }
#endif
Type[] constructorParamTypes = new Type[1];
@@ -299,14 +317,16 @@
}
object result = constructorInfo.Invoke(new object [] { constructorParamTypes[0] });
#if DEBUG
- Console.WriteLine("CreateInstance(\"{0}\") constructed {1}", className, result);
+ if ((Debug.DebugChannel() & QtDebugChannel.QTDB_GC) != 0) {
+ Console.WriteLine("CreateInstance(\"{0}\") constructed {1}", className, result);
+ }
#endif
Type[] paramTypes = new Type[0];
MethodInfo proxyCreator = klass.GetMethod("CreateProxy", BindingFlags.NonPublic
| BindingFlags.Instance
| BindingFlags.DeclaredOnly);
if (proxyCreator == null) {
- Console.WriteLine("CreateInstance() proxyCreator method missing");
+ Console.Error.WriteLine("CreateInstance() proxyCreator method missing");
return (IntPtr) 0;
}
proxyCreator.Invoke(result, null);
@@ -458,7 +478,7 @@
static private GetIntPtr getSmokeObject = new GetIntPtr(GetSmokeObject);
static private SetIntPtr setSmokeObject = new SetIntPtr(SetSmokeObject);
- static private SetIntPtr mapPointer = new SetIntPtr(MapPointer);
+ static private MapPointerFn mapPointer = new MapPointerFn(MapPointer);
static private FromIntPtr unmapPointer = new FromIntPtr(UnmapPointer);
static private GetIntPtr getPointerObject = new GetIntPtr(GetPointerObject);
--- trunk/playground/bindings/kimono/handlers.cpp #631667:631668
@@ -225,6 +225,48 @@
extern bool isDerivedFromByName(Smoke *smoke, const char *className, const char *baseClassName);
extern void mapPointer(void * obj, smokeqyoto_object *o, Smoke::Index classId, void *lastptr);
+bool
+CreateStrongReference(smokeqyoto_object *o)
+{
+ const char *className = o->smoke->classes[o->classId].className;
+
+ if ( qstrcmp(className, "QObject") == 0
+ || qstrcmp(className, "QListBoxItem") == 0
+ || qstrcmp(className, "QStyleSheetItem") == 0
+ || qstrcmp(className, "QSqlCursor") == 0
+ || qstrcmp(className, "QModelIndex") == 0 )
+ {
+ return true;
+ } else if (isDerivedFromByName(o->smoke, className, "QLayoutItem")) {
+ QLayoutItem * item = (QLayoutItem *) o->smoke->cast(o->ptr, o->classId, o->smoke->idClass("QLayoutItem"));
+ if (item->layout() != 0 || item->widget() != 0 || item->spacerItem() != 0) {
+ return true;
+ }
+ } else if (qstrcmp(className, "QListWidgetItem") == 0) {
+ QListWidgetItem * item = (QListWidgetItem *) o->ptr;
+ if (item->listWidget() != 0) {
+ return true;
+ }
+ } else if (isDerivedFromByName(o->smoke, className, "QTableWidgetItem")) {
+ QTableWidgetItem * item = (QTableWidgetItem *) o->smoke->cast(o->ptr, o->classId, o->smoke->idClass("QTableWidgetItem"));
+ if (item->tableWidget() != 0) {
+ return true;
+ }
+ } else if (isDerivedFromByName(o->smoke, className, "QWidget")) {
+ QWidget * qwidget = (QWidget *) o->smoke->cast(o->ptr, o->classId, o->smoke->idClass("QWidget"));
+ if (qwidget->parentWidget() != 0) {
+ return true;
+ }
+ } else if (isDerivedFromByName(o->smoke, className, "QObject")) {
+ QObject * qobject = (QObject *) o->smoke->cast(o->ptr, o->classId, o->smoke->idClass("QObject"));
+ if (qobject->parent() != 0) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
/*
* Given an approximate classname and a qt instance, try to improve the resolution of the name
* by using the various Qt rtti mechanisms for QObjects, QEvents and QCanvasItems
--- trunk/playground/bindings/kimono/qyoto.cpp #631667:631668
@@ -68,7 +68,7 @@
static GetIntPtr GetSmokeObject;
static SetIntPtr SetSmokeObject;
-static SetIntPtr MapPointer;
+static MapPointerFn MapPointer;
static FromIntPtr UnmapPointer;
static GetIntPtr GetPointerObject;
@@ -352,9 +352,13 @@
lastptr = ptr;
if (do_debug & qtdb_gc) {
const char *className = o->smoke->classes[o->classId].className;
- qWarning("mapPointer (%s*)%p -> %p", className, ptr, (void*)obj);
+ qWarning( "mapPointer (%s*)%p -> %p strong ref: %s",
+ className,
+ ptr,
+ (void*)obj,
+ CreateStrongReference(o) ? "true" : "false" );
}
- (*MapPointer)(ptr, obj);
+ (*MapPointer)(ptr, obj, CreateStrongReference(o));
}
for (Smoke::Index *i = o->smoke->inheritanceList + o->smoke->classes[classId].parents; *i; i++) {
@@ -1153,7 +1157,7 @@
}
void
-InstallMapPointer(SetIntPtr callback)
+InstallMapPointer(MapPointerFn callback)
{
MapPointer = callback;
}
--- trunk/playground/bindings/kimono/qyoto.h #631667:631668
@@ -58,6 +58,7 @@
void unmapPointer(smokeqyoto_object *, Smoke::Index, void*);
smokeqyoto_object *value_obj_info(void * value);
void * getPointerObject(void *ptr);
+bool CreateStrongReference(smokeqyoto_object *o);
typedef void* (*NoArgs)();
typedef void* (*GetIntPtr)(void *);
@@ -66,6 +67,7 @@
typedef void* (*GetIntPtrFromCharStar)(char *);
typedef void (*SetIntPtrFromCharStar)(void*, const char *);
typedef char* (*GetCharStarFromIntPtr)(void *);
+typedef void (*MapPointerFn)(void *, void *, bool);
typedef void* (*OverridenMethodFn)(void *, const char *);
typedef void (*InvokeMethodFn)(void *, void *, void *);
typedef void* (*CreateInstanceFn)(const char *);
More information about the Kde-bindings
mailing list