Mercurial > hg > vboxdotnet
view 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 source
???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("}"); } } } }