diff InteropCodeGen/Program.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 a7650e26195f
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/InteropCodeGen/Program.cs	Fri May 06 04:02:43 2011 +0200
@@ -0,0 +1,115 @@
+using System;
+using System.Xml.XPath;
+using System.Collections.Generic;
+using System.IO;
+using System.Runtime.InteropServices;
+
+namespace VBoxSDK {
+	class Program {
+		public static void Main(String[] args) {
+			Boolean TargetIsMono = false;
+
+			XidlParser parser = new XidlParser();
+			XPathDocument xidlDoc = new XPathDocument("VirtualBox.xidl");
+			if (TargetIsMono) {
+				parser.Types["wstring"] = new StringTypeInfo(UnmanagedType.LPWStr);
+				parser.BaseInterfaceType = parser.Library.Interfaces["IUnknown"];
+			} else {
+				parser.Types["wstring"] = new StringTypeInfo(UnmanagedType.BStr);
+				parser.BaseInterfaceType = parser.Library.Interfaces["IDispatch"];
+			}
+			parser.Parse(xidlDoc.CreateNavigator());
+			foreach (InterfaceInfo intf in parser.Library.Interfaces.Values) {
+				GnomeSort(intf.Members,	delegate(InterfaceMemberInfo a, InterfaceMemberInfo b) {
+					if (b is PropertyInfo && a is MethodInfo) return 1;
+					else if (a is PropertyInfo && b is MethodInfo) return -1;
+					return 0;
+				});
+			}
+			using (TextWriter outfile = File.CreateText("Interfaces.txt")) {
+				PrintTypeTree(outfile, parser.Library);
+			}
+			using (TextWriter outfile = File.CreateText("Interfaces.cs")) {
+				outfile.WriteLine("using System;");
+				outfile.WriteLine("using System.Runtime.InteropServices;");
+				outfile.WriteLine("using System.Runtime.CompilerServices;");
+				outfile.WriteLine("namespace VirtualBox {");
+				ComInteropInterfaceGenerator igen = new ComInteropInterfaceGenerator(outfile);
+				igen.IncludeInheritedMembers = true;
+				igen.IncludeComAttributes = true;
+				igen.ComInterfaceTypeIDispatch = !TargetIsMono;
+				igen.TypeModifiers = "public";
+				igen.WriteLibrary(parser.Library);
+				outfile.WriteLine("}");
+			}
+			parser.Library.Interfaces["IUnknown"].Members.Add(new MethodInfo("QueryInterface", new ValueTypeInfo("IntPtr")));
+			(parser.Library.Interfaces["IUnknown"].Members[0] as MethodInfo).Parameters.Add(new MethodParameterInfo("riid", new ValueTypeInfo("Guid"), true, true, false));
+			parser.Library.Interfaces["IUnknown"].Members.Add(new MethodInfo("AddRef", null));
+			parser.Library.Interfaces["IUnknown"].Members.Add(new MethodInfo("Release", null));
+			parser.Library.Interfaces["IDispatch"].Members.Add(new MethodInfo("GetTypeInfoCount", null));
+			parser.Library.Interfaces["IDispatch"].Members.Add(new MethodInfo("GetTypeInfo", null));
+			parser.Library.Interfaces["IDispatch"].Members.Add(new MethodInfo("GetIDsOfNames", null));
+			parser.Library.Interfaces["IDispatch"].Members.Add(new MethodInfo("Invoke", null));
+			parser.Library.Interfaces["IErrorInfo"].Members.Add(new MethodInfo("dummy1", null));
+			parser.Library.Interfaces["IErrorInfo"].Members.Add(new MethodInfo("dummy2", null));
+			parser.Library.Interfaces["IErrorInfo"].Members.Add(new MethodInfo("dummy3", null));
+			parser.Library.Interfaces["IErrorInfo"].Members.Add(new MethodInfo("dummy4", null));
+			parser.Library.Interfaces["IErrorInfo"].Members.Add(new MethodInfo("dummy5", null));
+			if (TargetIsMono) {
+				parser.Library.Interfaces["IErrorInfo"].Members.Add(new MethodInfo("dummy6", null));
+				parser.Library.Interfaces["IErrorInfo"].Members.Add(new MethodInfo("dummy7", null));
+				parser.Library.Interfaces["IErrorInfo"].Members.Add(new MethodInfo("dummy8", null));
+				parser.Library.Interfaces["IErrorInfo"].Members.Add(new MethodInfo("dummy9", null));
+				parser.Library.Interfaces["IErrorInfo"].Members.Add(new MethodInfo("dummy10", null));
+			}
+			using (TextWriter outfile = File.CreateText("Proxy.cs")) {
+				outfile.WriteLine("using System;");
+				outfile.WriteLine("using System.Runtime.InteropServices;");
+				outfile.WriteLine("using HRESULT = System.Int32;");
+				outfile.WriteLine("namespace VirtualBox {");
+				ComInteropProxyGenerator igen = new ComInteropProxyGenerator(outfile);
+				igen.IncludeInheritedMembers = true;
+				igen.TypeModifiers = "public";
+				igen.WriteLibrary(parser.Library);
+				outfile.WriteLine("}");
+			}
+			Console.WriteLine("Done.");
+			Console.ReadLine();
+		}
+		private static void GnomeSort<T>(IList<T> a, Comparison<T> comparer) {
+			int pos = 1;
+			while (pos < a.Count) {
+				if (comparer(a[pos], a[pos - 1]) >= 0) {
+					pos++;
+				} else {
+					T tmp = a[pos];
+					a[pos] = a[pos - 1];
+					a[pos - 1] = tmp;
+					if (pos > 1) pos--; else pos++;
+				}
+			}
+		}
+		private static void PrintTypeTree(TextWriter output, LibraryInfo lib) {
+			foreach (KeyValuePair<String, EnumInfo> enumi in lib.Enums) {
+				output.WriteLine("enum {0};", enumi.Key);
+			}
+			foreach (KeyValuePair<String, InterfaceInfo> intf in lib.Interfaces) {
+				output.Write("interface {0}({1}) ", intf.Key, intf.Value.IID);
+				if (intf.Value.Extends != null) output.Write(": {0} ", intf.Value.Extends.Name);
+				output.WriteLine("{");
+				foreach (InterfaceMemberInfo member in intf.Value.Members) {
+					if (member is PropertyInfo) {
+						PropertyInfo memberi = (PropertyInfo)member;
+						output.WriteLine("property {0};", memberi.Name);
+					} else if (member is MethodInfo) {
+						MethodInfo memberi = (MethodInfo)member;
+						output.WriteLine("method {0};", memberi.Name);
+					} else {
+						output.WriteLine("unknown member;");
+					}
+				}
+				output.WriteLine("}");
+			}
+		}
+	}
+}