[Kde-bindings] KDE/kdebindings/csharp/kimono/src
Arno Rehn
kde at arnorehn.de
Tue Jul 1 16:03:08 UTC 2008
SVN commit 826847 by arnorehn:
* Only create one application domain in KMonoPluginFactory.
* Cache already opened assemblies and their images.
CCMAIL: kde-bindings at kde.org
M +64 -20 kmonopluginfactory.cpp
--- trunk/KDE/kdebindings/csharp/kimono/src/kmonopluginfactory.cpp #826846:826847
@@ -54,20 +54,40 @@
void InitQyotoRuntime();
MonoDomain* domain;
- MonoAssembly* assembly;
- MonoObject* object;
- guint32 handle;
+
+ QHash<QString, MonoAssembly*> assemblies;
+ QHash<MonoAssembly*, MonoImage*> images;
+
+ MonoAssembly* qyotoAssembly;
+ MonoImage* qyotoImage;
+
+ QList<MonoObject*> objects;
+ QList<guint32> handles;
+
+ bool qyotoInitialized;
};
K_EXPORT_PLUGIN(KMonoPluginFactory)
KMonoPluginFactory::KMonoPluginFactory()
- : domain(0), assembly(0), object(0), handle(0)
+ : domain(0), qyotoAssembly(0), qyotoImage(0), qyotoInitialized(false)
{
}
KMonoPluginFactory::~KMonoPluginFactory()
{
- mono_gchandle_free(handle);
+ foreach(guint32 handle, handles)
+ mono_gchandle_free(handle);
+
+ if (qyotoImage)
+ mono_image_close(qyotoImage);
+ if (qyotoAssembly)
+ mono_assembly_close(qyotoAssembly);
+
+ foreach(MonoImage* img, images)
+ mono_image_close(img);
+ foreach(MonoAssembly* a, assemblies)
+ mono_assembly_close(a);
+
// FIXME: this should actually work
/*if (domain)
mono_jit_cleanup(domain);*/
@@ -76,14 +96,19 @@
void
KMonoPluginFactory::InitQyotoRuntime()
{
+ if (qyotoInitialized)
+ return;
+
// open the assembly 'qt-dotnet', look for Qyoto.SmokeInvocation.InitRuntime() and call it
// it seems that there's now way to call static c'tors explicitly, hence the extra method
- MonoAssembly* qyotoAssembly = mono_domain_assembly_open(domain, "qt-dotnet");
- MonoImage* qyotoImage = mono_assembly_get_image(qyotoAssembly);
+ qyotoAssembly = mono_domain_assembly_open(domain, "qt-dotnet");
+ qyotoImage = mono_assembly_get_image(qyotoAssembly);
MonoMethodDesc* desc = mono_method_desc_new("Qyoto.SmokeInvocation:InitRuntime()", true);
MonoClass* klass = mono_class_from_name(qyotoImage, "Qyoto", "SmokeInvocation");
MonoMethod* meth = mono_method_desc_search_in_class(desc, klass);
mono_runtime_invoke(meth, NULL, NULL, NULL);
+
+ qyotoInitialized = true;
}
QObject*
@@ -102,17 +127,30 @@
return 0;
}
- // initialize the JIT and open the assembly
- domain = mono_jit_init((const char*) path.toLatin1());
- assembly = mono_domain_assembly_open(domain, (const char*) path.toLatin1());
+ // initialize the JIT
+ if (!domain)
+ domain = mono_jit_init((const char*) path.toLatin1());
+
+ MonoAssembly* assembly;
+ if (assemblies.contains(path)) {
+ assembly = assemblies[path];
+ } else {
+ assembly = mono_domain_assembly_open(domain, (const char*) path.toLatin1());
+ if (!assembly) {
+ kWarning() << "Couldn't open assembly" << path;
+ return 0;
+ }
+ assemblies[path] = assembly;
+ }
- if (!assembly) {
- kWarning() << "Couldn't open assembly" << path;
- return 0;
+ MonoImage* image;
+ if (images.contains(assembly)) {
+ image = images[assembly];
+ } else {
+ image = mono_assembly_get_image(assembly);
+ images[assembly] = image;
}
- MonoImage* image = mono_assembly_get_image(assembly);
-
// a path in the form Foo/Bar.dll results in the class Bar in the namespace Foo
QFileInfo file(path);
QString nameSpace = file.dir().dirName();
@@ -131,13 +169,15 @@
}
// create an instance of the class
- object = mono_object_new(domain, klass);
+ MonoObject* object = mono_object_new(domain, klass);
if (!object) {
kWarning() << "Failed to create instance of class" << nameSpace + "." + className;
return 0;
}
+ objects << object;
+
// initialize the Qyoto runtime
InitQyotoRuntime();
@@ -164,11 +204,15 @@
(*FreeGCHandle)(list);
// get a handle to the object and pin it, so it won't be collected
- handle = mono_gchandle_new(object, true);
+ guint32 handle = mono_gchandle_new(object, true);
+ handles << handle;
// return the newly created QObject
smokeqyoto_object *o = (smokeqyoto_object*) (*GetSmokeObject)((void*) handle);
- QObject* qobject = reinterpret_cast<QObject*>(o->ptr);
- qobject->setParent(parent);
- return qobject;
+ if (o) {
+ QObject* qobject = reinterpret_cast<QObject*>(o->ptr);
+ qobject->setParent(parent);
+ return qobject;
+ } else
+ return 0;
}
More information about the Kde-bindings
mailing list