let バインディングのグローバル(?)関数の属性を取得
コードはかなり汚いです。
コードとして MSIL から CALL を探してきて、[CALL+1]したポインタを取得し、
そのポインタのメンバーを取得すると関数が取得出来ます。
MSILを触ることになるなんて、属性を取得したいだけなのに非常に面倒でした。
属性を扱う場合は基本クラスを作ってからの方が良さそうです。
module Common open System open System.IO open System.Text open System.Reflection /// ILからInvoke対象のメソッドポインタを取得して /// MethodInfoを取得する。 let GetInvokeMethodInfo (mb : MethodBase) = let m = mb.DeclaringType.Module; let il = mb.GetMethodBody().GetILAsByteArray() il |> Array.tryFindIndex((=)40uy) |> (fun s -> match s with | None -> None | Some p -> // スタックに入れる予定のメンバポインタを取得 (BitConverter.ToInt32(il, p+1)) |> m.ResolveMethod |> (fun mi -> match mi with | null -> None | _ -> Some(mi) ) ) let GetMethodInfo (t : Type) = let letfunc = t.IsClass && t.IsSerializable && t.IsNested && t.IsNestedAssembly if letfunc then let mi = t.GetMethod("Invoke") if mi <> null then mi.MethodHandle |> MethodBase.GetMethodFromHandle |> GetInvokeMethodInfo |> (fun simi -> match simi with | Some imi -> Some(imi :?> MethodInfo) | None -> Some(mi) // ←この辺適当 ) else None else None ///<summary> ///型にラベル属性をつける為のクラス ///</summary> [<AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = true)>] type LabelAttribute(text:string) = inherit Attribute() member this.Text = text static member GetLabel(value : Object) = match value with | null -> "" | v -> match GetMethodInfo(v.GetType()) with | Some x -> x.GetCustomAttributes( typeof<LabelAttribute>,false) |> (fun arr -> match arr.[0] with | :? LabelAttribute as att -> att.Text | _ -> "" ) | _ -> ""