[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