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