Mercurial > hg > vboxdotnet
view InteropCodeGen/ComInteropInterfaceGenerator.cs @ 6:e640ca67b819
Added extended COM interop code generator for interfaces and proxies
author | Ivo Smits |
---|---|
date | Fri, 06 May 2011 04:02:43 +0200 |
parents | |
children |
line wrap: on
line source
???using System; using System.Collections.Generic; using System.Text; using System.IO; namespace VBoxSDK { class ComInteropInterfaceGenerator { public TextWriter Output { get; private set; } public Boolean IncludeInheritedMembers { get; set; } public Boolean IncludeComAttributes { get; set; } public Boolean ComInterfaceTypeIDispatch { get; set; } public String TypeModifiers { get; set; } public ComInteropInterfaceGenerator(TextWriter output) { Output = output; } public void WriteLibrary(LibraryInfo lib) { foreach (KeyValuePair<String, EnumInfo> enumi in lib.Enums) { Output.WriteLine("{1} enum {0} {{", enumi.Key, TypeModifiers); foreach (KeyValuePair<String, Int32> value in enumi.Value.Values) { Output.WriteLine("{0} = {1},", value.Key, value.Value); } Output.WriteLine("}"); } foreach (KeyValuePair<String, InterfaceInfo> intf in lib.Interfaces) { if (IncludeComAttributes) { if (ComInterfaceTypeIDispatch) { Output.WriteLine("[InterfaceType(ComInterfaceType.InterfaceIsDual)]"); } else { Output.WriteLine("[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]"); } Output.WriteLine("[Guid(\"{0}\")]", intf.Value.IID); Output.WriteLine("[ComImport()]"); } Output.Write("{1} interface {0} ", intf.Key, TypeModifiers); if (intf.Value.Extends != null) Output.Write(": {0} ", intf.Value.Extends.Name); Output.WriteLine("{"); WriteInterfaceMembers(intf.Value); Output.WriteLine("}"); } } public void WriteInterfaceMembers(InterfaceInfo intf) { if (IncludeInheritedMembers && intf.Extends != null && intf.Extends.Name != "IUnknown") WriteInterfaceMembers(intf.Extends); WriteInterfaceMembers(intf.Members); } public void WriteInterfaceMembers(ICollection<InterfaceMemberInfo> members) { foreach (InterfaceMemberInfo member in members) { if (member is PropertyInfo) { PropertyInfo memberi = (PropertyInfo)member; if (!memberi.Gettable && !memberi.Settable) continue; Output.WriteLine("{0} {1} {{", memberi.Type.Name, memberi.Name); if (memberi.Gettable) { if (IncludeComAttributes) Output.Write("[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] "); if (IncludeComAttributes) WriteTypeComMarshalAttributes(memberi.Type, "return"); Output.WriteLine("get;"); } if (memberi.Settable) { if (IncludeComAttributes) Output.Write("[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] "); if (IncludeComAttributes) WriteTypeComMarshalAttributes(memberi.Type, "param"); Output.WriteLine("set;"); } Output.WriteLine("}"); } else if (member is MethodInfo) { MethodInfo memberi = (MethodInfo)member; if (IncludeComAttributes) Output.Write("[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] "); if (memberi.ReturnType == null) { Output.Write("void "); } else { if (IncludeComAttributes) WriteTypeComMarshalAttributes(memberi.ReturnType, "return"); Output.Write("{0} ", memberi.ReturnType.Name); } Output.Write("{0}(", memberi.Name); Boolean first = true; foreach (MethodParameterInfo param in memberi.Parameters) { if (first) { first = false; } else { Output.Write(", "); } if (IncludeComAttributes) WriteTypeComMarshalAttributes(param.Type, null); if (param.Output && !param.Input) Output.Write("out "); else if (param.Reference) Output.Write("ref "); Output.Write("{0} p{1}", param.Type.Name, param.Name); } Output.WriteLine(");"); } } } public void WriteTypeComMarshalAttributes(TypeInfo type, String paramType) { String MarshalAs = null; if (type is InterfaceTypeInfo) { MarshalAs = "Interface"; } else if (type is StringTypeInfo) { MarshalAs = (type as StringTypeInfo).UnmanagedType.ToString(); } if (MarshalAs != null) { Output.Write("["); if (paramType != null) Output.Write("{0}: ", paramType); Output.Write("MarshalAs(UnmanagedType.{0})] ", MarshalAs); } } } }