mono / dbus-sharp

DBus Sharp
http://mono.github.com/dbus-sharp
MIT License
77 stars 59 forks source link

implementor: Correct F# Event Identification #39

Closed arfbtwn closed 8 years ago

arfbtwn commented 10 years ago

The MethodInfo.IsSpecialName property doesn't appear to be set true for event add/remove methods produced with the F# compiler, even with the [<CLIEvent>] annotation applied to the event.

This appears partly due to F#'s generalisation of the signature for event handler delegate types, but also because we attempt to treat all methods equally when implementing them.

This patch provides a quick hack to solve the problem with minimal change to the TypeImplementor class.

arfbtwn commented 10 years ago

As I mention in the commit message above, this is essentially a quick hack to correct the behaviour in F#, a better solution can be found in #37.

This short test program demonstrates the problem on current master:

open System.Collections.Generic
open DBus

type StringVariantMap = Dictionary<string,obj>

type PropertiesChangedHandler = delegate of string * StringVariantMap * string[] -> unit

[<Interface ("org.freedesktop.DBus.Properties")>]
type IProperties =
    abstract member Get : string -> string -> obj 
    abstract member Set : string -> string -> obj -> unit
    abstract member GetAll : string -> StringVariantMap
    [<CLIEvent>]
    abstract member PropertiesChanged : IDelegateEvent<PropertiesChangedHandler>

let ofn = Bus.Session.GetObject<IProperties>("org.freedesktop.Notifications", new ObjectPath("/org/freedesktop/Notifications"))

leading to this output:

Unhandled Exception:
System.ArgumentException: Cannot create a struct with no fields
Parameter name: signature
            at DBus.Protocol.Signature.MakeStruct (Signature signature) [0x00000] in <filename unknown>:0 
            at DBus.Protocol.Signature.GetSig (System.Type type) [0x00000] in <filename unknown>:0 
            at DBus.TypeImplementer.SigsForMethod (System.Reflection.MethodInfo mi, DBus.Protocol.Signature& inSig, DBus.Protocol.Signature& outSig) [0x00000] in <filename unknown>:0 
            at DBus.TypeImplementer.GenHookupMethod (System.Reflection.Emit.ILGenerator ilg, System.Reflection.MethodInfo declMethod, System.Reflection.MethodInfo invokeMethod, System.String interface, System.String member) [0x00000] in <filename unknown>:0 
            at DBus.TypeImplementer.Implement (System.Reflection.Emit.TypeBuilder typeB, System.Type iface, System.String interfaceName) [0x00000] in <filename unknown>:0 
            at DBus.TypeImplementer.GetImplementation (System.Type declType) [0x00000] in <filename unknown>:0 
            at DBus.BusObject.GetObject (DBus.Connection conn, System.String bus_name, DBus.ObjectPath object_path, System.Type declType) [0x00000] in <filename unknown>:0 
            at DBus.Connection.GetObject (System.Type type, System.String bus_name, DBus.ObjectPath path) [0x00000] in <filename unknown>:0 
            at DBus.Connection.GetObject[IProperties] (System.String bus_name, DBus.ObjectPath path) [0x00000] in <filename unknown>:0 
            at <StartupCode$helloevents>.$Helloevents.main@ () [0x00000] in <filename unknown>:0