[Kde-bindings] KDE/kdebindings

Arno Rehn arno at arnorehn.de
Tue Jun 10 17:53:57 UTC 2008


Am Dienstag 10 Juni 2008 15:26:54 schrieb Richard Dale:
> On Tuesday 10 June 2008 13:21:54 Arno Rehn wrote:
> > Am Montag 09 Juni 2008 20:49:25 schrieb Richard Dale:
> > > On Monday 09 June 2008 18:13:43 Arno Rehn wrote:
> > > > Am Montag 09 Juni 2008 15:28:21 schrieb Richard Dale:
> > > > > On Monday 09 June 2008 13:28:13 Arno Rehn wrote:
> > > > > > > The only thing I don't like is subclassing SmokeInvocation and
> > > > > > > giving it a different name in the generated code. That seems
> > > > > > > pointless and ugly to me any old static constructor will load
> > > > > > > the smoke lib. In the soprano bindings I had a source called
> > > > > > > 'Soprano.cs' with this:
> > > > > > >
> > > > > > > namespace Soprano {
> > > > > > >       using Qyoto;
> > > > > > >       using System;
> > > > > > >       using System.Runtime.InteropServices;
> > > > > > >
> > > > > > >       public class InitSoprano {
> > > > > > >               [DllImport("libsoprano-sharp",
> > > > > > > CharSet=CharSet.Ansi)] static extern void Init_soprano();
> > > > > > >
> > > > > > >               static InitSoprano() {
> > > > > > >                       Init_soprano();
> > > > > > >               }
> > > > > > >       }
> > > > > > > }
> > > > > > >
> > > > > > > And just left SmokeInvocation as it was in the generated code.
> > > > > > > So I think we should have a Kimono.cs source with the same
> > > > > > > thing in it.
> > > > > >
> > > > > > My intention was to simplify the code for those who actually use
> > > > > > the C# bindings. And a static constructor is called when the
> > > > > > class that defines it is used for the first time. Since
> > > > > > SmokeInvocation is always used before any other thing, it makes
> > > > > > sure that the smoke lib is always loaded. If we put that code
> > > > > > into another class that is completely unrelated to the binding,
> > > > > > we will always have to call InitFoo() if we want to use it. So
> > > > > > subclassing SmokeInvocation for the different bindings seemed to
> > > > > > be the best solution to me.
> > > > >
> > > > > OK, I understand the problem now, but I still think the solution of
> > > > > renaming SmokeInvocation is ugly. I found this after a bit of
> > > > > googling:
> > > > >
> > > > > "Note, however, that you *can* put code in your AppDomain to
> > > > > execute when *another* DLL loads. (The AppDomain.AssemblyLoad
> > > > > event.) That means you can write your code once, and so long as
> > > > > that event handler is added before the other assemblies are loaded,
> > > > > you can do all the appropriate things."
> > > > >
> > > > > http://osdir.com/ml/windows.devel.dotnet.cx/2004-01/msg00064.html
> > > > >
> > > > > So is the Qyoto dll in an AppDomain, or can we put it in one?
> > > >
> > > > Yes, of couse the Qyoto dll is always in an AppDomain. So we'd have
> > > > to define a standard class class name, whoch holds a method to do the
> > > > initialization. Whenever an assembly is loaded, we have to look for
> > > > that class via reflection and call the initialization method.
> > >
> > > I've read a bit more about this, and it seems quite straightforward to
> > > implement - you just set up a static delegate that receives the dll
> > > loaded event and then do what you say. So I would prefer doing it this
> > > way - an app domain called 'Qyoto' and an initialize class called
> > > InitSmoke in each dll for instance.
> >
> > Ok, I just tested this and it doesn't quite work out. Consider this:
> >
> > using System;
> > using Qyoto;
> >
> > class MainClass {
> > 	public static void AssemblyLoad(object sender, AssemblyLoadEventArgs
> > args) { Console.WriteLine(args.LoadedAssembly.FullName);
> > 	}
> >
> > 	public static void Main(string[] args) {
> > 		AppDomain.CurrentDomain.AssemblyLoad += AssemblyLoad;
> > // 		System.Reflection.Assembly.Load("qt-dotnet, Version=4.4.0.0,
> > Culture=neutral, PublicKeyToken=194a23ba31c08164");
> > 	}
> > }
> >
> > This will do nothing, since we add the event handler _after_ the assembly
> > is loaded. The same will happen if we define such an event handler in the
> > Qyoto runtime. If we load the assembly dynamically, it will work well. So
> > going via AppDomain.AssemblyLoad is not really an option, I think.
>
> Shouldn't the qt smoke lib be initialized via the static constructor in
> SmokeInvocation, but the other ones are done by the reflection calls in
> response to the AssemblyLoad events?
Yes. The problem is, that there are no AssemblyLoad events.

> As far as I can see you are only testing it with the first dll, the Qyoto
> one, whereas we need the mechanism for just the subsequent ones once the
> event handler is in place in the qyoto dll.
This test is not connected with the Qyoto dll in any way, I simply took it as 
an example. What I wanted to show is that if you reference an assembly at 
compile time like in
	gmcs -r:qt-dotnet test.cs
this assembly will be loaded _before_ any code is executed; it will be done 
before the Main() method. So we won't have any event handler in place that 
can initialize other smoke libs. Only if we load the assembly dynamically, 
that means by code and not passed as a reference to the compiler, we can set 
up the event handler before we load the assembly. Then we can do all the 
stuff we want. But this is not comfortable in any way, noone would ever use 
that.


-- 
Arno Rehn
arno at arnorehn.de



More information about the Kde-bindings mailing list