view InteropCodeGen/ComInteropInterfaceGenerator.cs @ 7:a7650e26195f default tip

Added support for generating Com Callable Wrappers
author Ivo Smits
date Fri, 06 May 2011 08:12:43 +0200
parents e640ca67b819
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);
			}
		}
	}
}