[Kde-bindings] KDE/kdebindings
Richard Dale
rdale at foton.es
Wed Jun 11 09:25:02 UTC 2008
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.
So when Qyoto.Qyoto.Init_qyoto() is called in the SmokeInvocation static
constructor all the assemblies are already loaded?
If that is so, I think we just need to add a custom Attribute to the Qyoto
assemblies (apart from the qt dll):
[AttributeUsage(AttributeTargets.Assembly)]
public class AssemblySmokeInitializer : Attribute
{
public string initializer;
public string Initializer {
get {
return initializer;
}
}
public AssemblySmokeInitializer(string initializer) {
this.initializer = initializer;
}
}
Then in each AssemblyInfo.cs:
// The class to initialize the smoke library used by this assembly
// Type.GetType("Soprano.InitSoprano")
[assembly: AssemblySmokeInitializer("Soprano.InitSoprano")]
Does Type.GetType() load the class? If so, it should called the init method
for the smoke lib in the InitSoprano class:
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();
}
}
}
In the SmokeInvocation static constructor we need to iterate though the loaded
assemblies looking for AssemblySmokeInitializer attributes and load the named
classes.
-- Richard
More information about the Kde-bindings
mailing list