[Kde-bindings] KDE/kdebindings/csharp
Arno Rehn
kde at arnorehn.de
Mon Jul 7 00:42:31 UTC 2008
SVN commit 828931 by arnorehn:
* KimonoPluginFactory: If a class isn't found in the assembly, look
through all of the classes and pick the first one that implements
the interface and has a matching constructor.
* Allow to call InitRuntime() multiple times to make sure that every
binding is initialized.
CCMAIL: kde-bindings at kde.org
M +8 -0 kimono/ChangeLog
M +66 -21 kimono/src/kimonopluginfactory.cpp
M +5 -0 qyoto/ChangeLog
M +12 -6 qyoto/src/SmokeInvocation.cs
--- trunk/KDE/kdebindings/csharp/kimono/ChangeLog #828930:828931
@@ -1,3 +1,11 @@
+2008-07-07 Arno Rehn <arno at arnorehn.de>
+
+ * KimonoPluginFactory: If a class isn't found in the assembly, look
+ through all of the classes and pick the first one that implements
+ the interface and has a matching constructor.
+ * Allow to call InitRuntime() multiple times to make sure that every
+ binding is initialized.
+
2008-07-06 Arno Rehn <arno at arnorehn.de>
* mono_jit_cleanup() is now called from a function that is registered
--- trunk/KDE/kdebindings/csharp/kimono/src/kimonopluginfactory.cpp #828930:828931
@@ -56,17 +56,17 @@
private:
void initQyotoRuntime();
QByteArray camelize(QByteArray name);
+ QList<const char*> assemblyGetClasses(const char* path);
QHash<QString, MonoAssembly*> assemblies;
QHash<MonoAssembly*, MonoImage*> images;
MonoAssembly* qyotoAssembly;
MonoImage* qyotoImage;
+ MonoMethod* initRuntimeMethod;
QList<MonoObject*> objects;
QList<guint32> handles;
-
- bool qyotoInitialized;
};
K_EXPORT_PLUGIN(KimonoPluginFactory)
@@ -82,7 +82,7 @@
}
KimonoPluginFactory::KimonoPluginFactory()
- : qyotoAssembly(0), qyotoImage(0), qyotoInitialized(false)
+ : qyotoAssembly(0), qyotoImage(0), initRuntimeMethod(0)
{
}
@@ -109,22 +109,47 @@
return camelCaseName;
}
+QList<const char*>
+KimonoPluginFactory::assemblyGetClasses(const char* path)
+{
+ static MonoImage* corlib = mono_get_corlib();
+ static MonoMethodDesc* assemblyLoadFromDesc = mono_method_desc_new("System.Reflection.Assembly:LoadFrom(string)", true);
+ static MonoMethod* assemblyLoadFrom = mono_method_desc_search_in_image(assemblyLoadFromDesc, corlib);
+
+ void* args[1];
+ args[0] = mono_string_new(domain, path);
+ MonoObject* assembly = mono_runtime_invoke(assemblyLoadFrom, NULL, args, NULL);
+
+ static MonoMethodDesc* assemblyGetTypesDesc = mono_method_desc_new("System.Reflection.Assembly:GetTypes()", true);
+ static MonoMethod* assemblyGetTypes = mono_method_desc_search_in_image(assemblyGetTypesDesc, corlib);
+
+ MonoArray* types = (MonoArray*) mono_runtime_invoke(assemblyGetTypes, assembly, NULL, NULL);
+
+ static MonoClass* type = mono_class_from_name(corlib, "System", "MonoType");
+ static MonoProperty* typeFullName = mono_class_get_property_from_name(type, "FullName");
+
+ QList<const char*> ret;
+ for (int i = 0; i < mono_array_length(types); i++) {
+ MonoObject* obj = mono_array_get(types, MonoObject*, i);
+ ret << mono_string_to_utf8((MonoString*) mono_property_get_value(typeFullName, obj, NULL, NULL));
+ }
+
+ return ret;
+}
+
void
KimonoPluginFactory::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
- 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;
+ if (!initRuntimeMethod) {
+ 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");
+ initRuntimeMethod = mono_method_desc_search_in_class(desc, klass);
+ }
+ mono_runtime_invoke(initRuntimeMethod, NULL, NULL, NULL);
}
QObject*
@@ -176,14 +201,34 @@
QString className = camelize(file.completeBaseName().toLatin1());
MonoClass* klass = mono_class_from_name(image, (const char*) nameSpace.toLatin1(), (const char*) className.toLatin1());
- // we want the Foo.Bar:.ctor(QObject, List<QVariant>)
- QString methodName = nameSpace + "." + className + ":.ctor(Qyoto.QObject,System.Collections.Generic.List`1)";
- MonoMethodDesc* desc = mono_method_desc_new((const char*) methodName.toLatin1(), true);
-
- MonoMethod* ctor = mono_method_desc_search_in_class(desc, klass);
-
+ MonoMethod* ctor = 0;
+ if (klass) {
+ // we want the Foo.Bar:.ctor(QObject, List<QVariant>)
+ QString methodName = nameSpace + "." + className + ":.ctor(Qyoto.QObject,System.Collections.Generic.List`1)";
+ MonoMethodDesc* desc = mono_method_desc_new((const char*) methodName.toLatin1(), true);
+ ctor = mono_method_desc_search_in_class(desc, klass);
+ } else {
+ QString ifacestr(iface);
+ ifacestr.replace("::", ".");
+ foreach(QString name, assemblyGetClasses((const char*) path.toLatin1())) {
+ nameSpace = name.left(name.lastIndexOf("."));
+ className = name.right(name.size() - name.lastIndexOf(".") - 1);
+ klass = mono_class_from_name(image, (const char*) nameSpace.toLatin1(), (const char*) className.toLatin1());
+ MonoClass* p = klass;
+ do {
+ if (ifacestr != mono_type_get_name(mono_class_get_type(p)))
+ continue;
+ QString methodName = nameSpace + "." + className + ":.ctor(Qyoto.QObject,System.Collections.Generic.List`1)";
+ MonoMethodDesc* desc = mono_method_desc_new((const char*) methodName.toLatin1(), 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) {
- kWarning() << "Didn't find method" << methodName << "in class" << nameSpace + "." + className;
+ kWarning() << "Didn't find a matching constructor in the classes of the assembly";
return 0;
}
--- trunk/KDE/kdebindings/csharp/qyoto/ChangeLog #828930:828931
@@ -1,3 +1,8 @@
+2008-07-07 Arno Rehn <arno at arnorehn.de>
+
+ * Allow to call InitRuntime() multiple times to make sure every binding
+ is initialized.
+
2008-07-06 Richard Dale <richard.j.dale at gmail.com>
* Where multiple inheritance was catered for in the Qyoto bindings each
--- trunk/KDE/kdebindings/csharp/qyoto/src/SmokeInvocation.cs #828930:828931
@@ -425,19 +425,25 @@
}
static bool runtimeInitialized = false;
+ static List<Assembly> initializedAssemblies = new List<Assembly>();
public static void InitRuntime() {
- if (runtimeInitialized)
- return;
- Qyoto.Init_qyoto();
- SmokeMarshallers.SetUp();
+ if (!runtimeInitialized) {
+ Qyoto.Init_qyoto();
+ SmokeMarshallers.SetUp();
+ runtimeInitialized = true;
+ }
// initialize other referenced smoke bindings
foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies()) {
+ if (initializedAssemblies.Contains(a)) return;
AssemblySmokeInitializer attr = (AssemblySmokeInitializer) Attribute.GetCustomAttribute(a, typeof(AssemblySmokeInitializer));
- if (attr != null) attr.CallInitSmoke();
+ if (attr != null) {
+ Console.WriteLine("Init {0}", a);
+ attr.CallInitSmoke();
+ }
+ initializedAssemblies.Add(a);
}
- runtimeInitialized = true;
}
static SmokeInvocation() {
More information about the Kde-bindings
mailing list