diff 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 diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/InteropCodeGen/ComInteropInterfaceGenerator.cs	Fri May 06 04:02:43 2011 +0200
@@ -0,0 +1,103 @@
+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);
+			}
+		}
+	}
+}