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

Arno Rehn kde at arnorehn.de
Mon Oct 27 22:12:42 UTC 2008


SVN commit 876733 by arnorehn:

* Add support for Mono based kio slaves by extending kimonopluginfactory.
* Add a kio_monodoc example kio slave. It needs monodoc installed and
  accessible through 'pkg-config --libs monodoc'.
  You can then access the mono documentation by typing e.g.
    monodoc:/T:System.Object
    monodoc:/N:System.Reflection
  in Konqueror's address bar or using kioclient from the command line.
  Simply monodoc:/ will bring you to monodoc:/N:System

CCMAIL: kde-bindings at kde.org



 M  +2 -1      CMakeLists.txt  
 M  +11 -0     ChangeLog  
 A             examples (directory)  
 A             examples/CMakeLists.txt  
 A             examples/kio (directory)  
 A             examples/kio/CMakeLists.txt  
 A             examples/kio/kio_monodoc (directory)  
 A             examples/kio/kio_monodoc/CMakeLists.txt  
 A             examples/kio/kio_monodoc/kio_monodoc.cs  
 A             examples/kio/kio_monodoc/monodoc.protocol  
 M  +171 -28   src/kimonopluginfactory.cpp  


--- trunk/KDE/kdebindings/csharp/kimono/CMakeLists.txt #876732:876733
@@ -33,7 +33,7 @@
     INCLUDE_DIRECTORIES(${MONO_INCLUDES} ${GLIB_INCLUDES})
     ADD_DEFINITIONS(${GLIB_CFLAGS} ${MONO_CFLAGS})
     KDE4_ADD_PLUGIN(kimonopluginfactory ${SRC_FACTORY})
-    TARGET_LINK_LIBRARIES(kimonopluginfactory ${KDE4_KDECORE_LIBS} qyotoshared ${MONO_LINK_FLAGS})
+    TARGET_LINK_LIBRARIES(kimonopluginfactory ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${KDE4_KDECORE_LIBS} ${KDE4_KIO_LIBS} qyotoshared ${MONO_LINK_FLAGS})
     INSTALL(TARGETS kimonopluginfactory DESTINATION ${PLUGIN_INSTALL_DIR})
 ELSE (MONO_INCLUDES)
     MESSAGE(STATUS "Mono includes not found. kimonopluginfactory will not be compiled.")
@@ -47,3 +47,4 @@
 INSTALL_GAC(kde-dotnet)
 
 add_subdirectory(tutorials EXCLUDE_FROM_ALL)
+add_subdirectory(examples EXCLUDE_FROM_ALL)
--- trunk/KDE/kdebindings/csharp/kimono/ChangeLog #876732:876733
@@ -1,3 +1,14 @@
+2008-10-27  Arno Rehn  <arno at arnorehn.de>
+
+	* Add support for Mono based kio slaves by extending kimonopluginfactory.
+	* Add a kio_monodoc example kio slave. It needs monodoc installed and
+	  accessible through 'pkg-config --libs monodoc'.
+	  You can then access the mono documentation by typing e.g.
+	    monodoc:/T:System.Object
+	    monodoc:/N:System.Reflection
+	  in Konqueror's address bar or using kioclient from the command line.
+	  Simply monodoc:/ will bring you to monodoc:/N:System
+
 2008-08-13  Arno Rehn  <arno at arnorehn.de>
 
     * Make the KSharedPointer marshaller more generic and add one for
--- trunk/KDE/kdebindings/csharp/kimono/src/kimonopluginfactory.cpp #876732:876733
@@ -25,6 +25,7 @@
 
 #include <KStandardDirs>
 #include <KPluginFactory>
+#include <KIO/SlaveBase>
 
 #include <kdebug.h>
 
@@ -48,6 +49,17 @@
 public:
 	KimonoPluginFactory();
 	virtual ~KimonoPluginFactory();
+	
+	void initQyotoRuntime();
+	
+	MonoDomain* initJit(const QString& path);
+	MonoAssembly* getAssembly(const QString& path);
+	MonoImage* getImage(MonoAssembly* assembly);
+	MonoObject* createInstance(MonoClass* klass);
+	guint32 pinObject(MonoObject* obj);
+	
+	static QByteArray camelize(QByteArray name);
+	static QList<const char*> assemblyGetClasses(const char* path);
 
 protected:
 	virtual QObject* create(const char *iface, QWidget *parentWidget,
@@ -55,10 +67,6 @@
 	                        const QString &keyword);
 
 private:
-	void initQyotoRuntime();
-	QByteArray camelize(QByteArray name);
-	QList<const char*> assemblyGetClasses(const char* path);
-	
 	QHash<QString, MonoAssembly*> assemblies;
 	QHash<MonoAssembly*, MonoImage*> images;
 	
@@ -153,22 +161,9 @@
 	mono_runtime_invoke(initRuntimeMethod, NULL, NULL, NULL);
 }
 
-QObject*
-KimonoPluginFactory::create(const char *iface, QWidget *parentWidget,
-	                       QObject *parent, const QVariantList &args,
-	                       const QString &keyword)
+MonoDomain*
+KimonoPluginFactory::initJit(const QString& path)
 {
-	Q_UNUSED(iface);
-	Q_UNUSED(parentWidget);
-
-	// find the assembly
-	QString path = KStandardDirs::locate("data", keyword);
-
-	if (path.isEmpty()) {
-		kWarning() << "Couldn't find" << keyword;
-		return 0;
-	}
-
 	// initialize the JIT
 	if (!domain) {
 		domain = mono_jit_init((const char*) path.toLatin1());
@@ -176,7 +171,12 @@
 // 		printf("(kimonopluginfactory.cpp:%d) new domain (ptr: %p)\n", __LINE__, domain);
 		atexit(atexitfn);
 	}
-	
+	return domain;
+}
+
+MonoAssembly*
+KimonoPluginFactory::getAssembly(const QString& path)
+{
 	MonoAssembly* assembly;
 	if (assemblies.contains(path)) {
 		assembly = assemblies[path];
@@ -188,7 +188,12 @@
 		}
 		assemblies[path] = assembly;
 	}
+	return assembly;
+}
 
+MonoImage*
+KimonoPluginFactory::getImage(MonoAssembly* assembly)
+{
 	MonoImage* image;
 	if (images.contains(assembly)) {
 		image = images[assembly];
@@ -196,7 +201,51 @@
 		image = mono_assembly_get_image(assembly);
 		images[assembly] = image;
 	}
+	return image;
+}
 
+MonoObject*
+KimonoPluginFactory::createInstance(MonoClass* klass)
+{
+	// create an instance of the class
+	MonoObject* object = mono_object_new(domain, klass);
+	if (!object) return 0;
+	objects << object;
+	return object;
+}
+
+guint32
+KimonoPluginFactory::pinObject(MonoObject* obj)
+{
+	guint32 handle = mono_gchandle_new(obj, true);
+	handles << handle;
+	return handle;
+}
+
+QObject*
+KimonoPluginFactory::create(const char *iface, QWidget *parentWidget,
+	                       QObject *parent, const QVariantList &args,
+	                       const QString &keyword)
+{
+	Q_UNUSED(iface);
+	Q_UNUSED(parentWidget);
+
+	// find the assembly
+	QString path = KStandardDirs::locate("data", keyword);
+
+	if (path.isEmpty()) {
+		kWarning() << "Couldn't find" << keyword;
+		return 0;
+	}
+
+	initJit(path);
+
+	MonoAssembly* assembly = getAssembly(path);
+	if (!assembly) return 0;
+	
+	MonoImage* image = getImage(assembly);
+	if (!image) return 0;
+
 	// a path in the form Foo/Bar.dll results in the class Bar in the namespace Foo
 	QFileInfo file(path);
 	QByteArray nameSpace = KimonoPluginFactory::camelize(QFile::encodeName(file.dir().dirName()));
@@ -234,16 +283,12 @@
 		return 0;
 	}
 	
-	// create an instance of the class
-	MonoObject* object = mono_object_new(domain, klass);
-	
-	if (!object) {
+	MonoObject* object = createInstance(klass);
+	if (!object) { 
 		kWarning() << "Failed to create instance of class" << nameSpace + "." + className;
 		return 0;
 	}
 	
-	objects << object;
-	
 	// initialize the Qyoto runtime
 	initQyotoRuntime();
 	
@@ -270,8 +315,7 @@
 	(*FreeGCHandle)(list);
 	
 	// get a handle to the object and pin it, so it won't be collected
-	guint32 handle = mono_gchandle_new(object, true);
-	handles << handle;
+	guint32 handle = pinObject(object);
 	
 	// return the newly created QObject
 	smokeqyoto_object *o = (smokeqyoto_object*) (*GetSmokeObject)((void*) handle);
@@ -282,3 +326,102 @@
 	} else
 		return 0;
 }
+
+extern "C" { Q_DECL_EXPORT int kdemain(int argc, char** argv); }
+
+int kdemain(int argc, char** argv)
+{
+	if (argc != 4) {
+		printf("USAGE: kimonopluginfactory protocol pool_sock app_sock");
+		return -1;
+	}
+
+	KComponentData("kimonopluginfactory");
+
+	KimonoPluginFactory factory;
+
+	QByteArray protocol(argv[1]);
+	QByteArray pool_sock(argv[2]);
+	QByteArray app_sock(argv[3]);
+
+	// find the assembly
+	QString keyword("kio_");
+	keyword.append(protocol);
+	keyword.append("/main.dll");
+	QString path = KStandardDirs::locate("data", keyword);
+
+	if (path.isEmpty()) {
+		kWarning() << "Couldn't find" << keyword;
+		return -1;
+	}
+
+	factory.initJit(path);
+
+	MonoAssembly* assembly = factory.getAssembly(path);
+	if (!assembly) return -1;
+	
+	MonoImage* image = factory.getImage(assembly);
+	if (!image) return -1;
+
+	MonoMethod* ctor = 0;
+	MonoClass* klass = 0;
+	QByteArray iface("KIO.SlaveBase");
+	QByteArray nameSpace, className;
+	foreach(QByteArray name, factory.assemblyGetClasses((const char*) path.toLatin1())) {
+		nameSpace = name.left(name.lastIndexOf("."));
+		className = name.right(name.size() - name.lastIndexOf(".") - 1);
+		klass = mono_class_from_name(image, nameSpace, className);
+		MonoClass* p = klass;
+		do {
+			if (iface != mono_type_get_name(mono_class_get_type(p)))
+				continue;
+			QByteArray methodName = nameSpace + "." + className + ":.ctor(Qyoto.QByteArray,Qyoto.QByteArray,Qyoto.QByteArray)";
+			MonoMethodDesc* desc = mono_method_desc_new(methodName, true);
+			ctor = mono_method_desc_search_in_class(desc, klass);
+			if (ctor) break;
+		} while ((p = mono_class_get_parent(p)));
+		if (ctor) break;
+	}
+
+	if (!ctor || !klass) {
+		kWarning() << "FATAL: Didn't find a class implementing KIO.SlaveBase or with a matching constructor.";
+		return -1;
+	}
+
+	MonoObject* object = factory.createInstance(klass);
+	if (!object) { 
+		kWarning() << "Failed to create instance of class" << nameSpace + "." + className;
+		return -1;
+	}
+
+	factory.initQyotoRuntime();
+
+	smokeqyoto_object* sqo_p = alloc_smokeqyoto_object(false, qt_Smoke, qt_Smoke->idClass("QByteArray").index, &protocol);
+	void* p = (*CreateInstance)("Qyoto.QByteArray", sqo_p);
+	
+	smokeqyoto_object* sqo_ps = alloc_smokeqyoto_object(false, qt_Smoke, qt_Smoke->idClass("QByteArray").index, &pool_sock);
+	void* ps = (*CreateInstance)("Qyoto.QByteArray", sqo_ps);
+	
+	smokeqyoto_object* sqo_as = alloc_smokeqyoto_object(false, qt_Smoke, qt_Smoke->idClass("QByteArray").index, &app_sock);
+	void* as = (*CreateInstance)("Qyoto.QByteArray", sqo_as);
+	
+	void* a[3];
+	a[0] = mono_gchandle_get_target((guint32) (qint64) p);
+	a[1] = mono_gchandle_get_target((guint32) (qint64) ps);
+	a[2] = mono_gchandle_get_target((guint32) (qint64) as);
+	mono_runtime_invoke(ctor, object, a, NULL);
+	(*FreeGCHandle)(p);
+	(*FreeGCHandle)(ps);
+	(*FreeGCHandle)(as);
+	
+	guint32 handle = factory.pinObject(object);
+	
+	smokeqyoto_object *o = (smokeqyoto_object*) (*GetSmokeObject)((void*) handle);
+	if (o) {
+		KIO::SlaveBase *slave = (KIO::SlaveBase*) o->ptr;
+		slave->dispatchLoop();
+		delete slave;
+		return 0;
+	} else
+		return -1;
+}



More information about the Kde-bindings mailing list