Mercurial > hg > vboxdotnet
view InteropCodeGen/gendotnet.cs @ 1:55ca098c88d0
Added disclaimer
author | Ivo Smits |
---|---|
date | Wed, 04 May 2011 01:06:22 +0200 |
parents | e1ec7bf71313 |
children | f1deea9c97a0 |
line wrap: on
line source
//+reference System.dll //+reference System.Xml.dll using System; using System.Xml.XPath; using System.IO; using System.Collections.Generic; class Program { enum ParameterType { In, Out, Reference, Return, Param, } class TypeInfo { public String Name { get; private set; } public String[] Attributes { get; private set; } //public Boolean InputOnly { get; private set; } public String Members { get; set; } public TypeInfo(String name, params String[] attributes) { this.Name = name; this.Attributes = attributes; } /*public TypeInfo(String name, bool inputOnly, params String[] attributes) : this(name, attributes) { this.InputOnly = inputOnly; }*/ /*public static TypeInfo CreateInterfaceWithMembers(String name, String members) { TypeInfo ret = new TypeInfo(name, "MarshalAs(UnmanagedType.Interface)"); ret.Members = members; return ret; }*/ //Todo: if attribute mod="string"/"ptr" ... public void WriteDeclaration(TextWriter o, ParameterType vartype) { WriteAttributes(o, vartype); o.Write(Name); } public void WriteAttributes(TextWriter o, ParameterType vartype) { //if (InputOnly && vartype != ParameterType.In) { foreach (String attribute in Attributes) { o.Write("["); if (vartype == ParameterType.Return) o.Write("return: "); else if (vartype == ParameterType.Param) o.Write("param: "); o.Write(attribute); o.Write("] "); } if (vartype == ParameterType.Out) o.Write("out "); else if (vartype == ParameterType.Reference) o.Write("ref "); } } static Dictionary<String, TypeInfo> Types = new Dictionary<string, TypeInfo>(); static void InitTypes() { Types.Add("short", new TypeInfo("Int16")); Types.Add("unsigned short", new TypeInfo("UInt16")); Types.Add("unsigned long", new TypeInfo("UInt32")); Types.Add("long long", new TypeInfo("Int64")); Types.Add("long", new TypeInfo("Int32")); Types.Add("octet", new TypeInfo("Byte")); Types.Add("unsigned long long", new TypeInfo("UInt32")); //Types.Add("boolean", new TypeInfo("Boolean", "MarshalAs(UnmanagedType.Bool)")); Types.Add("boolean", new TypeInfo("Int32")); Types.Add("wstring", new TypeInfo("String", "MarshalAs(UnmanagedType.LPWStr)")); //Types.Add("uuid", new TypeInfo("Guid", true, "MarshalAs(UnmanagedType.LPStruct)")); Types.Add("uuid", new TypeInfo("Guid", "MarshalAs(UnmanagedType.LPStruct)")); Types.Add("IMachine", new TypeInfo("IMachine", "MarshalAs(UnmanagedType.Interface)")); Types.Add("ISession", new TypeInfo("ISession", "MarshalAs(UnmanagedType.Interface)")); Types.Add("IVirtualBox", new TypeInfo("IVirtualBox", "MarshalAs(UnmanagedType.Interface)")); Types.Add("IHost", new TypeInfo("IHost", "MarshalAs(UnmanagedType.Interface)")); Types.Add("IConsole", new TypeInfo("IConsole", "MarshalAs(UnmanagedType.Interface)")); Types.Add("ISystemProperties", new TypeInfo("ISystemProperties", "MarshalAs(UnmanagedType.Interface)")); Types.Add("IProgress", new TypeInfo("IProgress", "MarshalAs(UnmanagedType.Interface)")); Types.Add("IDisplay", new TypeInfo("IDisplay", "MarshalAs(UnmanagedType.Interface)")); Types.Add("IMouse", new TypeInfo("IMouse", "MarshalAs(UnmanagedType.Interface)")); Types.Add("IKeyboard", new TypeInfo("IKeyboard", "MarshalAs(UnmanagedType.Interface)")); Types.Add("IFramebuffer", new TypeInfo("IFramebuffer", "MarshalAs(UnmanagedType.Interface)")); Types.Add("IFramebufferOverlay", new TypeInfo("IFramebufferOverlay", "MarshalAs(UnmanagedType.Interface)")); Types.Add("IMachineDebugger", new TypeInfo("IMachineDebugger", "MarshalAs(UnmanagedType.Interface)")); Types.Add("IVirtualBoxErrorInfo", new TypeInfo("IVirtualBoxErrorInfo", "MarshalAs(UnmanagedType.Interface)")); Types.Add("IEventSource", new TypeInfo("IEventSource", "MarshalAs(UnmanagedType.Interface)")); Types.Add("IEventListener", new TypeInfo("IEventListener", "MarshalAs(UnmanagedType.Interface)")); Types.Add("IEventContext", new TypeInfo("IEventContext", "MarshalAs(UnmanagedType.Interface)")); Types.Add("IConsoleCallback", new TypeInfo("IConsoleCallback", "MarshalAs(UnmanagedType.Interface)")); Types.Add("IEvent", new TypeInfo("IEvent", "MarshalAs(UnmanagedType.Interface)")); Types.Add("LockType", new TypeInfo("LockType")); Types.Add("MediumVariant", new TypeInfo("MediumVariant")); Types.Add("AccessMode", new TypeInfo("AccessMode")); Types.Add("NATProtocol", new TypeInfo("NATProtocol")); Types.Add("FirmwareType", new TypeInfo("FirmwareType")); Types.Add("StorageControllerType", new TypeInfo("StorageControllerType")); Types.Add("StorageBus", new TypeInfo("StorageBus")); Types.Add("SessionType", new TypeInfo("SessionType")); Types.Add("SessionState", new TypeInfo("SessionState")); Types.Add("USBDeviceState", new TypeInfo("USBDeviceState")); Types.Add("USBDeviceFilterAction", new TypeInfo("USBDeviceFilterAction")); Types.Add("AudioControllerType", new TypeInfo("AudioControllerType")); Types.Add("AudioDriverType", new TypeInfo("AudioDriverType")); Types.Add("VRDPAuthType", new TypeInfo("VRDPAuthType")); Types.Add("MachineState", new TypeInfo("MachineState")); Types.Add("NetworkAdapterType", new TypeInfo("NetworkAdapterType")); Types.Add("NetworkAttachmentType", new TypeInfo("NetworkAttachmentType")); Types.Add("PortMode", new TypeInfo("PortMode")); Types.Add("DeviceType", new TypeInfo("DeviceType")); Types.Add("MediumState", new TypeInfo("MediumState")); Types.Add("MediumType", new TypeInfo("MediumType")); Types.Add("HostNetworkInterfaceType", new TypeInfo("HostNetworkInterfaceType")); Types.Add("DeviceActivity", new TypeInfo("DeviceActivity")); Types.Add("HostNetworkInterfaceMediumType", new TypeInfo("HostNetworkInterfaceMediumType")); Types.Add("HostNetworkInterfaceStatus", new TypeInfo("HostNetworkInterfaceStatus")); Types.Add("ProcessorFeature", new TypeInfo("ProcessorFeature")); Types.Add("VFSType", new TypeInfo("VFSType")); Types.Add("BIOSBootMenuMode", new TypeInfo("BIOSBootMenuMode")); Types.Add("VirtualSystemDescriptionType", new TypeInfo("VirtualSystemDescriptionType")); Types.Add("VirtualSystemDescriptionValueType", new TypeInfo("VirtualSystemDescriptionValueType")); Types.Add("KeyboardHidType", new TypeInfo("KeyboardHidType")); Types.Add("ClipboardMode", new TypeInfo("ClipboardMode")); Types.Add("PointingHidType", new TypeInfo("PointingHidType")); Types.Add("CPUPropertyType", new TypeInfo("CPUPropertyType")); Types.Add("HWVirtExPropertyType", new TypeInfo("HWVirtExPropertyType")); Types.Add("Scope", new TypeInfo("Scope")); Types.Add("ChipsetType", new TypeInfo("ChipsetType")); Types.Add("FaultToleranceState", new TypeInfo("FaultToleranceState")); Types.Add("BandwidthGroupType", new TypeInfo("BandwidthGroupType")); Types.Add("VBoxEventType", new TypeInfo("VBoxEventType")); Types.Add("GuestMonitorChangedEventType", new TypeInfo("GuestMonitorChangedEventType")); Types.Add("AuthType", new TypeInfo("AuthType")); Types.Add("NetworkAdapterPromiscModePolicy", new TypeInfo("NetworkAdapterPromiscModePolicy")); Types.Add("ExecuteProcessStatus", new TypeInfo("ExecuteProcessStatus")); Types.Add("AdditionsRunLevelType", new TypeInfo("AdditionsRunLevelType")); Types.Add("AdditionsFacilityStatus", new TypeInfo("AdditionsFacilityStatus")); Types.Add("AdditionsFacilityType", new TypeInfo("AdditionsFacilityType")); Types.Add("AdditionsFacilityClass", new TypeInfo("AdditionsFacilityClass")); Types.Add("CleanupMode", new TypeInfo("CleanupMode")); Types.Add("DataType", new TypeInfo("DataType")); Types.Add("IBandwidthControl", new TypeInfo("IntPtr")); Types.Add("IVRDEServerInfo", new TypeInfo("IntPtr")); Types.Add("IAdditionsFacility", new TypeInfo("IntPtr")); Types.Add("IExtPackPlugIn", new TypeInfo("IntPtr")); Types.Add("IExtPackFile", new TypeInfo("IntPtr")); Types.Add("IExtPack", new TypeInfo("IntPtr")); Types.Add("IBIOSSettings", new TypeInfo("IntPtr")); Types.Add("IVFSExplorer", new TypeInfo("IntPtr")); Types.Add("IUSBController", new TypeInfo("IntPtr")); Types.Add("IStorageController", new TypeInfo("IntPtr")); Types.Add("IVRDPServer", new TypeInfo("IntPtr")); Types.Add("ISnapshot", new TypeInfo("IntPtr")); Types.Add("INATEngine", new TypeInfo("IntPtr")); Types.Add("IUSBDeviceFilter", new TypeInfo("IntPtr")); Types.Add("IMediumAttachment", new TypeInfo("IntPtr")); Types.Add("IUSBDevice", new TypeInfo("IntPtr")); Types.Add("IParallelPort", new TypeInfo("IntPtr")); Types.Add("ISerialPort", new TypeInfo("IntPtr")); Types.Add("INetworkAdapter", new TypeInfo("IntPtr")); Types.Add("IMedium", new TypeInfo("IntPtr")); Types.Add("IGuestOSType", new TypeInfo("IntPtr")); Types.Add("ISharedFolder", new TypeInfo("IntPtr")); Types.Add("IPerformanceCollector", new TypeInfo("IntPtr")); Types.Add("IDHCPServer", new TypeInfo("IntPtr")); Types.Add("IAppliance", new TypeInfo("IntPtr")); Types.Add("IVirtualBoxCallback", new TypeInfo("IntPtr")); Types.Add("IPerformanceMetric", new TypeInfo("IntPtr")); Types.Add("IMediumFormat", new TypeInfo("IntPtr")); Types.Add("IHostUSBDevice", new TypeInfo("IntPtr")); Types.Add("IHostNetworkInterface", new TypeInfo("IntPtr")); Types.Add("IHostUSBDeviceFilter", new TypeInfo("IntPtr")); Types.Add("IRemoteDisplayInfo", new TypeInfo("IntPtr")); Types.Add("IGuest", new TypeInfo("IntPtr")); Types.Add("IVirtualSystemDescription", new TypeInfo("IntPtr")); Types.Add("IAudioAdapter", new TypeInfo("IntPtr")); Types.Add("IExtPackManager", new TypeInfo("IntPtr")); Types.Add("IVRDEServer", new TypeInfo("IntPtr")); Types.Add("IPciDeviceAttachment", new TypeInfo("IntPtr")); Types.Add("IBandwidthGroup", new TypeInfo("IntPtr")); Types.Add("$unknown", new TypeInfo("IntPtr")); } static void Main(string[] args) { InitTypes(); XPathDocument doc = new XPathDocument("VirtualBox.xidl"); XPathNavigator nav = doc.CreateNavigator(); nav = nav.SelectSingleNode("/idl/library[@name='VirtualBox']"); TextWriter o = Console.Out; o.WriteLine("using System;"); o.WriteLine("using System.Runtime.CompilerServices;"); o.WriteLine("using System.Runtime.InteropServices;"); o.WriteLine("namespace VirtualBox {"); foreach (XPathNavigator intf in nav.Select("interface")) { ProcessInterface(intf, o, nav); } foreach (XPathNavigator intf in nav.Select("enum")) { ProcessEnum(intf, o); } o.WriteLine("}"); } static void ProcessEnum(XPathNavigator nav, TextWriter o) { String typeName = nav.SelectSingleNode("@name").Value; if (!Types.ContainsKey(typeName)) Types.Add(typeName, new TypeInfo(typeName)); o.WriteLine("[Guid(\"{0}\")]", nav.SelectSingleNode("@uuid").Value); o.WriteLine("enum " + typeName + " {"); foreach (XPathNavigator member in nav.SelectChildren(XPathNodeType.Element)) { switch (member.Name) { case "desc": break; case "const": o.WriteLine("\t{0} = {1},", member.SelectSingleNode("@name").Value, member.SelectSingleNode("@value").Value); break; default: Console.Error.WriteLine("Unknown member type {0}", member.Name); break; } } o.WriteLine("}"); } static void ProcessInterface(XPathNavigator nav, TextWriter o, XPathNavigator parentNav) { String typeName = nav.SelectSingleNode("@name").Value; if (!Types.ContainsKey(typeName)) Types.Add(typeName, new TypeInfo(typeName, "MarshalAs(UnmanagedType.Interface)")); o.WriteLine("[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]"); o.WriteLine("[Guid(\"{0}\")]", nav.SelectSingleNode("@uuid").Value); o.WriteLine("[ComImport()]"); o.Write("interface " + typeName); o.WriteLine(" {"); ProcessInterfaceMembersAndInherited(nav, o, parentNav); o.WriteLine("}"); } static void ProcessInterfaceMembersAndInherited(XPathNavigator nav, TextWriter o, XPathNavigator parentNav) { XPathItem item = nav.SelectSingleNode("@extends"); if (item != null && item.Value[0] != '$') { XPathNavigator inav = parentNav.SelectSingleNode("interface[@name='" + item.Value + "']"); ProcessInterfaceMembersAndInherited(inav, o, parentNav); } ProcessInterfaceMembers(nav.SelectChildren(XPathNodeType.Element), o); } static void ProcessInterfaceMembers(XPathNodeIterator members, TextWriter oattribute) { XPathItem item; StringWriter omethod = new StringWriter(); foreach (XPathNavigator member in members) { switch (member.Name) { case "desc": break; case "attribute": { String mName = member.SelectSingleNode("@name").Value; //String mType = member.SelectSingleNode("@type").Value; item = member.SelectSingleNode("@readonly"); Boolean mReadOnly = item == null ? false : item.Value == "yes"; //item = member.SelectSingleNode("@mod"); //String mMod = item == null ? null : item.Value; mName = mName.Substring(0, 1).ToUpper() + mName.Substring(1); oattribute.Write("\t"); /*TypeInfo t; if (mMod == "ptr") { t = new TypeInfo("IntPtr"); } else if (mMod == "string") { t = new TypeInfo("String", "MarshalAs(UnmanagedType.LPWStr)"); } else if (mMod == null) { if (!Types.TryGetValue(mType, out t)) { Console.Error.WriteLine("Type {0} is not supported", mType); t = new TypeInfo("void"); } } else { Console.Error.WriteLine("Type modifier {0} is not supported", mMod); t = new TypeInfo("void"); }*/ TypeInfo t = GetTypeDeclaration(member); oattribute.Write(t.Name); oattribute.Write(" "); oattribute.Write(mName); oattribute.WriteLine(" {"); oattribute.Write("\t\t[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] "); t.WriteAttributes(oattribute, ParameterType.Return); oattribute.WriteLine("get;"); if (!mReadOnly) { oattribute.Write("\t\t[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] "); t.WriteAttributes(oattribute, ParameterType.Param); oattribute.WriteLine("set;"); } oattribute.WriteLine("\t}"); } break; case "method": { String mName = member.SelectSingleNode("@name").Value; XPathNodeIterator mParamReturn = member.Select("param[@dir='return']"); omethod.WriteLine("\t[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]"); omethod.Write("\t"); bool mReturn = false; if (mParamReturn == null || mParamReturn.Count != 1) { omethod.Write("void"); } else { mParamReturn.MoveNext(); mReturn = true; TypeInfo t = GetTypeDeclaration(mParamReturn.Current); /*String mType = mParamReturn.Current.SelectSingleNode("@type").Value; TypeInfo t; if (!Types.TryGetValue(mType, out t)) { Console.Error.WriteLine("Type {0} is not supported", mType); t = new TypeInfo("void"); mReturn = false; }*/ t.WriteDeclaration(omethod, ParameterType.Return); } mName = mName.Substring(0, 1).ToUpper() + mName.Substring(1); omethod.Write(" "); omethod.Write(mName); omethod.Write("("); XPathNodeIterator mParams = member.Select("param"); bool first = true; if (mParams.MoveNext()) { while (true) { XPathNavigator mParam = mParams.Current; String pDir = mParam.SelectSingleNode("@dir").Value; //item = mParam.SelectSingleNode("@safearray"); //Boolean pArray = item == null ? false : item.Value == "yes"; //item = mParam.SelectSingleNode("@mod"); //String pMod = item == null ? null : item.Value; if (pDir == "return" && mReturn) { if (mParams.MoveNext()) { continue; } else { break; } } else if (pDir == "in") { } else if (pDir == "out") { } else { Console.Error.WriteLine("Unsupported parameter direction {0}", pDir); } if (first) { first = false; } else { omethod.Write(", "); } ParameterType pt = ParameterType.In; if (pDir == "out") pt = ParameterType.Out; TypeInfo t = GetTypeDeclaration(mParam, ref pt); t.WriteDeclaration(omethod, pt); /*if (pArray) { omethod.Write("[MarshalAs(UnmanagedType.SafeArray)] "); if (pDir == "out") omethod.Write("out "); else omethod.Write("ref "); omethod.Write("System.Array"); } else { String pType = mParam.SelectSingleNode("@type").Value; TypeInfo t; if (!Types.TryGetValue(pType, out t)) { Console.Error.WriteLine("Type {0} is not supported", pType); t = new TypeInfo("IntPtr"); mReturn = false; } if (pMod == "ptr") { t.WriteDeclaration(omethod, ParameterType.Reference); } else if (pDir == "out") { t.WriteDeclaration(omethod, ParameterType.Out); } else { t.WriteDeclaration(omethod, ParameterType.In); } }*/ omethod.Write(" p"); omethod.Write(mParam.SelectSingleNode("@name").Value); if (!mParams.MoveNext()) break; } } omethod.WriteLine(");"); } break; default: Console.Error.WriteLine("Unknown member type {0}", member.Name); break; } } oattribute.Write((omethod as StringWriter).ToString()); } private static TypeInfo GetTypeDeclaration(XPathNavigator nav) { ParameterType pt = ParameterType.Param; return GetTypeDeclaration(nav, ref pt); } private static TypeInfo GetTypeDeclaration(XPathNavigator nav, ref ParameterType paramType) { String mType = nav.SelectSingleNode("@type").Value; XPathItem item; item = nav.SelectSingleNode("@mod"); String mMod = item == null ? null : item.Value; item = nav.SelectSingleNode("@safearray"); Boolean pArray = item == null ? false : item.Value == "yes"; TypeInfo t; if (!Types.TryGetValue(mType, out t)) { Console.Error.WriteLine("Type {0} is not supported", mType); t = new TypeInfo("void"); } if (mMod == "ptr") { if (paramType == ParameterType.In) { paramType = ParameterType.Reference; } else { t = new TypeInfo("IntPtr"); } } else if (mMod == "string") { t = new TypeInfo("String", "MarshalAs(UnmanagedType.LPWStr)"); } else if (mMod != null) { Console.Error.WriteLine("Type modifier {0} is not supported", mMod); t = new TypeInfo("void"); } if (pArray) { t = new TypeInfo("Array", "MarshalAs(UnmanagedType.SafeArray)"); if (paramType == ParameterType.In || paramType == ParameterType.Out) paramType = ParameterType.Reference; } return t; } }