[Kde-bindings] KDE/kdebindings/csharp/qyoto

Arno Rehn kde at arnorehn.de
Sun Apr 12 19:21:50 UTC 2009


SVN commit 952887 by arnorehn:

You can now register .NET types as metatypes, too, and use them in QVariants.

CCMAIL: kde-bindings at kde.org



 M  +2 -2      ChangeLog  
 M  +20 -6     core/QMetaTypeExtras.cs  
 M  +12 -4     src/SmokeMarshallers.cs  
 M  +4 -3      src/qyoto.cpp  


--- trunk/KDE/kdebindings/csharp/qyoto/ChangeLog #952886:952887
@@ -1,6 +1,6 @@
 2009-04-12  Arno Rhen  <arno at arnorehn.de>
-	* Make it possible to register new metatypes. For the moment this works only
-	  with classes wrapped by SMOKE.
+	* Make it possible to register new metatypes. Works also with non-smoke
+	  types, i.e. all .NET types.
 
 2009-03-24  Arno Rehn  <arno at arnorehn.de>
 	* Change Qyoto's license to LGPL2.
--- trunk/KDE/kdebindings/csharp/qyoto/core/QMetaTypeExtras.cs #952886:952887
@@ -37,14 +37,28 @@
         static extern int QMetaTypeRegisterType(string name, Destructor dtor, Constructor ctor);
 
         public static int RegisterType<T>() {
+            string className;
+            Destructor dtorHandler;
+            Constructor ctorHandler;
             if (SmokeMarshallers.IsSmokeClass(typeof(T))) {
-                string className = SmokeMarshallers.SmokeClassName(typeof(T));
-                GCHandle.Alloc(className); // prevent collection
-                Destructor dtorHandler = delegate(IntPtr obj) { DestroyObject(className, obj); };
-                Constructor ctorHandler = delegate(IntPtr copy) { return CreateObject(className, copy); };
-                return QMetaTypeRegisterType(className, dtorHandler, ctorHandler);
+                className = SmokeMarshallers.SmokeClassName(typeof(T));
+                dtorHandler = delegate(IntPtr obj) { DestroyObject(className, obj); };
+                ctorHandler = delegate(IntPtr copy) { return CreateObject(className, copy); };
+            } else {
+                className = typeof(T).ToString();
+                dtorHandler = delegate(IntPtr obj) { ((GCHandle) obj).Free(); };
+                ctorHandler = delegate(IntPtr copy) {
+                    if (copy != IntPtr.Zero) {
+                        T o = (T) ((GCHandle) copy).Target;  // create a copy
+                        return (IntPtr) GCHandle.Alloc(o);
+                    }
+                    return (IntPtr) GCHandle.Alloc(default(T));
+                };
             }
-            return 0;
+            GCHandle.Alloc(className); // prevent collection
+            GCHandle.Alloc(dtorHandler);
+            GCHandle.Alloc(ctorHandler);
+            return QMetaTypeRegisterType(className, dtorHandler, ctorHandler);
         }
     }
 }
--- trunk/KDE/kdebindings/csharp/qyoto/src/SmokeMarshallers.cs #952886:952887
@@ -264,8 +264,12 @@
 			Object instance = ((GCHandle) instancePtr).Target;
 //			Debug.Assert(instance != null);
 
-			SmokeClassData data = GetSmokeClassData(instance.GetType());
-			return (IntPtr) data.smokeObjectField.GetValue(instance);
+			try {
+				SmokeClassData data = GetSmokeClassData(instance.GetType());
+				return (IntPtr) data.smokeObjectField.GetValue(instance);
+			} catch {
+				return IntPtr.Zero;
+			}
 		}
 		
 		public static void SetSmokeObject(IntPtr instancePtr, IntPtr smokeObjectPtr) {
@@ -557,8 +561,12 @@
 		// The class is not a custom subclass of a Qyoto class, and also is not
 		// a superclass of a Qyoto class, such as a MarshalByRefObject.
 		public static bool IsSmokeClass(Type klass) {
-			SmokeClassData data = GetSmokeClassData(klass);
-			return data != null && data.className != null;
+			try {
+				SmokeClassData data = GetSmokeClassData(klass);
+				return data != null && data.className != null;
+			} catch {
+				return false;
+			}
 		}
 
 		// The C++ class name signature of a Smoke class or interface
--- trunk/KDE/kdebindings/csharp/qyoto/src/qyoto.cpp #952886:952887
@@ -363,6 +363,7 @@
 	}
 	
 	Smoke::ModuleIndex id = o->smoke->findClass(typeName);
+	if (!id.smoke) return value;  // class not found in smoke, so it's probably just a GCHandle
 	smokeqyoto_object  * vo = alloc_smokeqyoto_object(true, id.smoke, id.index, value);
 	return (*CreateInstance)(qyoto_resolve_classname(vo), vo);
 }
@@ -374,10 +375,10 @@
 	printf("ENTER QVariantFromValue(type: %d value: 0x%8.8x)\n", type, value);
 #endif
 	smokeqyoto_object *o = (smokeqyoto_object*) (*GetSmokeObject)(value);
-	QVariant * v = new QVariant(type, o->ptr);
-	Smoke::ModuleIndex id = o->smoke->findClass("QVariant");
+	if (o) (*FreeGCHandle)(value);
+	QVariant * v = new QVariant(type, o? o->ptr : value);
+	Smoke::ModuleIndex id = qt_Smoke->findClass("QVariant");
 	smokeqyoto_object  * vo = alloc_smokeqyoto_object(true, id.smoke, id.index, (void *) v);
-	(*FreeGCHandle)(value);
 	return (*CreateInstance)("Qyoto.QVariant", vo);
 }
 



More information about the Kde-bindings mailing list