Mercurial > hg > vboxdotnet
annotate InteropCodeGen/gendotnet.cs @ 2:f1deea9c97a0
Cleaned up the interop code generator, added wrapper application to initialize kernel driver and run mono
author | Ivo Smits |
---|---|
date | Wed, 04 May 2011 16:10:08 +0200 |
parents | e1ec7bf71313 |
children | 64226294e26b |
rev | line source |
---|---|
0 | 1 //+reference System.dll |
2 //+reference System.Xml.dll | |
3 using System; | |
4 using System.Xml.XPath; | |
5 using System.IO; | |
6 using System.Collections.Generic; | |
7 class Program { | |
8 enum ParameterType { | |
9 In, | |
10 Out, | |
11 Reference, | |
12 Return, | |
13 Param, | |
14 } | |
15 class TypeInfo { | |
16 public String Name { get; private set; } | |
17 public String[] Attributes { get; private set; } | |
18 | |
19 public TypeInfo(String name, params String[] attributes) { | |
20 this.Name = name; | |
21 this.Attributes = attributes; | |
22 } | |
23 public void WriteDeclaration(TextWriter o, ParameterType vartype) { | |
24 WriteAttributes(o, vartype); | |
25 o.Write(Name); | |
26 } | |
27 public void WriteAttributes(TextWriter o, ParameterType vartype) { | |
28 foreach (String attribute in Attributes) { | |
29 o.Write("["); | |
30 if (vartype == ParameterType.Return) o.Write("return: "); | |
31 else if (vartype == ParameterType.Param) o.Write("param: "); | |
32 o.Write(attribute); | |
33 o.Write("] "); | |
34 } | |
35 if (vartype == ParameterType.Out) o.Write("out "); | |
36 else if (vartype == ParameterType.Reference) o.Write("ref "); | |
37 } | |
38 } | |
39 static Dictionary<String, TypeInfo> Types = new Dictionary<string, TypeInfo>(); | |
2
f1deea9c97a0
Cleaned up the interop code generator, added wrapper application to initialize kernel driver and run mono
Ivo Smits
parents:
0
diff
changeset
|
40 static void AddInterfaceTypes(params String[] names) { |
f1deea9c97a0
Cleaned up the interop code generator, added wrapper application to initialize kernel driver and run mono
Ivo Smits
parents:
0
diff
changeset
|
41 foreach (String name in names) Types.Add(name, new TypeInfo(name, "MarshalAs(UnmanagedType.Interface)")); |
f1deea9c97a0
Cleaned up the interop code generator, added wrapper application to initialize kernel driver and run mono
Ivo Smits
parents:
0
diff
changeset
|
42 } |
f1deea9c97a0
Cleaned up the interop code generator, added wrapper application to initialize kernel driver and run mono
Ivo Smits
parents:
0
diff
changeset
|
43 static void AddEnumTypes(params String[] names) { |
f1deea9c97a0
Cleaned up the interop code generator, added wrapper application to initialize kernel driver and run mono
Ivo Smits
parents:
0
diff
changeset
|
44 foreach (String name in names) Types.Add(name, new TypeInfo(name)); |
f1deea9c97a0
Cleaned up the interop code generator, added wrapper application to initialize kernel driver and run mono
Ivo Smits
parents:
0
diff
changeset
|
45 } |
0 | 46 static void InitTypes() { |
47 Types.Add("short", new TypeInfo("Int16")); | |
48 Types.Add("unsigned short", new TypeInfo("UInt16")); | |
49 Types.Add("unsigned long", new TypeInfo("UInt32")); | |
50 Types.Add("long long", new TypeInfo("Int64")); | |
51 Types.Add("long", new TypeInfo("Int32")); | |
52 Types.Add("octet", new TypeInfo("Byte")); | |
53 Types.Add("unsigned long long", new TypeInfo("UInt32")); | |
54 //Types.Add("boolean", new TypeInfo("Boolean", "MarshalAs(UnmanagedType.Bool)")); | |
55 Types.Add("boolean", new TypeInfo("Int32")); | |
56 Types.Add("wstring", new TypeInfo("String", "MarshalAs(UnmanagedType.LPWStr)")); | |
57 //Types.Add("uuid", new TypeInfo("Guid", true, "MarshalAs(UnmanagedType.LPStruct)")); | |
58 Types.Add("uuid", new TypeInfo("Guid", "MarshalAs(UnmanagedType.LPStruct)")); | |
2
f1deea9c97a0
Cleaned up the interop code generator, added wrapper application to initialize kernel driver and run mono
Ivo Smits
parents:
0
diff
changeset
|
59 Types.Add("$unknown", new TypeInfo("IntPtr")); |
0 | 60 |
2
f1deea9c97a0
Cleaned up the interop code generator, added wrapper application to initialize kernel driver and run mono
Ivo Smits
parents:
0
diff
changeset
|
61 AddInterfaceTypes("IMachine", "ISession", "IVirtualBox", "IHost", "IConsole", "ISystemProperties"); |
f1deea9c97a0
Cleaned up the interop code generator, added wrapper application to initialize kernel driver and run mono
Ivo Smits
parents:
0
diff
changeset
|
62 AddInterfaceTypes("IProgress", "IDisplay", "IMouse", "IKeyboard", "IFramebuffer", "IFramebufferOverlay"); |
f1deea9c97a0
Cleaned up the interop code generator, added wrapper application to initialize kernel driver and run mono
Ivo Smits
parents:
0
diff
changeset
|
63 AddInterfaceTypes("IMachineDebugger", "IVirtualBoxErrorInfo", "IEventSource", "IEventListener", "IEventContext"); |
f1deea9c97a0
Cleaned up the interop code generator, added wrapper application to initialize kernel driver and run mono
Ivo Smits
parents:
0
diff
changeset
|
64 AddInterfaceTypes("IConsoleCallback", "IEvent", "IBandwidthControl", "IVRDEServerInfo", "IAdditionsFacility"); |
f1deea9c97a0
Cleaned up the interop code generator, added wrapper application to initialize kernel driver and run mono
Ivo Smits
parents:
0
diff
changeset
|
65 AddInterfaceTypes("IExtPackPlugIn", "IExtPackFile", "IExtPack", "IBIOSSettings", "IVFSExplorer", "IUSBController"); |
f1deea9c97a0
Cleaned up the interop code generator, added wrapper application to initialize kernel driver and run mono
Ivo Smits
parents:
0
diff
changeset
|
66 AddInterfaceTypes("IStorageController", "IVRDPServer", "ISnapshot", "INATEngine", "IUSBDeviceFilter"); |
f1deea9c97a0
Cleaned up the interop code generator, added wrapper application to initialize kernel driver and run mono
Ivo Smits
parents:
0
diff
changeset
|
67 AddInterfaceTypes("IMediumAttachment", "IUSBDevice", "IParallelPort", "ISerialPort", "INetworkAdapter"); |
f1deea9c97a0
Cleaned up the interop code generator, added wrapper application to initialize kernel driver and run mono
Ivo Smits
parents:
0
diff
changeset
|
68 AddInterfaceTypes("IMedium", "IGuestOSType", "ISharedFolder", "IPerformanceCollector", "IDHCPServer"); |
f1deea9c97a0
Cleaned up the interop code generator, added wrapper application to initialize kernel driver and run mono
Ivo Smits
parents:
0
diff
changeset
|
69 AddInterfaceTypes("IAppliance", "IVirtualBoxCallback", "IPerformanceMetric", "IMediumFormat", "IHostUSBDevice"); |
f1deea9c97a0
Cleaned up the interop code generator, added wrapper application to initialize kernel driver and run mono
Ivo Smits
parents:
0
diff
changeset
|
70 AddInterfaceTypes("IHostNetworkInterface", "IHostUSBDeviceFilter", "IRemoteDisplayInfo", "IGuest"); |
f1deea9c97a0
Cleaned up the interop code generator, added wrapper application to initialize kernel driver and run mono
Ivo Smits
parents:
0
diff
changeset
|
71 AddInterfaceTypes("IVirtualSystemDescription", "IAudioAdapter", "IExtPackManager", "IVRDEServer"); |
f1deea9c97a0
Cleaned up the interop code generator, added wrapper application to initialize kernel driver and run mono
Ivo Smits
parents:
0
diff
changeset
|
72 AddInterfaceTypes("IPciDeviceAttachment", "IBandwidthGroup"); |
f1deea9c97a0
Cleaned up the interop code generator, added wrapper application to initialize kernel driver and run mono
Ivo Smits
parents:
0
diff
changeset
|
73 |
f1deea9c97a0
Cleaned up the interop code generator, added wrapper application to initialize kernel driver and run mono
Ivo Smits
parents:
0
diff
changeset
|
74 AddEnumTypes("LockType", "MediumVariant", "AccessMode", "NATProtocol", "FirmwareType", "StorageControllerType"); |
f1deea9c97a0
Cleaned up the interop code generator, added wrapper application to initialize kernel driver and run mono
Ivo Smits
parents:
0
diff
changeset
|
75 AddEnumTypes("StorageBus", "SessionType", "SessionState", "USBDeviceState", "USBDeviceFilterAction"); |
f1deea9c97a0
Cleaned up the interop code generator, added wrapper application to initialize kernel driver and run mono
Ivo Smits
parents:
0
diff
changeset
|
76 AddEnumTypes("AudioControllerType", "AudioDriverType", "VRDPAuthType", "MachineState", "NetworkAdapterType"); |
f1deea9c97a0
Cleaned up the interop code generator, added wrapper application to initialize kernel driver and run mono
Ivo Smits
parents:
0
diff
changeset
|
77 AddEnumTypes("NetworkAttachmentType", "PortMode", "DeviceType", "MediumState", "VFSType", "MediumType"); |
f1deea9c97a0
Cleaned up the interop code generator, added wrapper application to initialize kernel driver and run mono
Ivo Smits
parents:
0
diff
changeset
|
78 AddEnumTypes("HostNetworkInterfaceType", "DeviceActivity", "HostNetworkInterfaceMediumType", "HostNetworkInterfaceStatus"); |
f1deea9c97a0
Cleaned up the interop code generator, added wrapper application to initialize kernel driver and run mono
Ivo Smits
parents:
0
diff
changeset
|
79 AddEnumTypes("ProcessorFeature", "BIOSBootMenuMode", "VirtualSystemDescriptionType", "VirtualSystemDescriptionValueType"); |
f1deea9c97a0
Cleaned up the interop code generator, added wrapper application to initialize kernel driver and run mono
Ivo Smits
parents:
0
diff
changeset
|
80 AddEnumTypes("KeyboardHidType", "ClipboardMode", "PointingHidType", "CPUPropertyType", "HWVirtExPropertyType"); |
f1deea9c97a0
Cleaned up the interop code generator, added wrapper application to initialize kernel driver and run mono
Ivo Smits
parents:
0
diff
changeset
|
81 AddEnumTypes("ChipsetType", "FaultToleranceState", "BandwidthGroupType", "ExecuteProcessStatus", "VBoxEventType"); |
f1deea9c97a0
Cleaned up the interop code generator, added wrapper application to initialize kernel driver and run mono
Ivo Smits
parents:
0
diff
changeset
|
82 AddEnumTypes("GuestMonitorChangedEventType", "AuthType", "NetworkAdapterPromiscModePolicy", "AdditionsRunLevelType"); |
f1deea9c97a0
Cleaned up the interop code generator, added wrapper application to initialize kernel driver and run mono
Ivo Smits
parents:
0
diff
changeset
|
83 AddEnumTypes("AdditionsFacilityStatus", "AdditionsFacilityType", "AdditionsFacilityClass", "CleanupMode", "DataType"); |
0 | 84 } |
85 static void Main(string[] args) { | |
86 InitTypes(); | |
87 | |
88 XPathDocument doc = new XPathDocument("VirtualBox.xidl"); | |
89 XPathNavigator nav = doc.CreateNavigator(); | |
90 nav = nav.SelectSingleNode("/idl/library[@name='VirtualBox']"); | |
91 TextWriter o = Console.Out; | |
92 o.WriteLine("using System;"); | |
93 o.WriteLine("using System.Runtime.CompilerServices;"); | |
94 o.WriteLine("using System.Runtime.InteropServices;"); | |
95 o.WriteLine("namespace VirtualBox {"); | |
96 foreach (XPathNavigator intf in nav.Select("interface")) { | |
97 ProcessInterface(intf, o, nav); | |
98 } | |
99 foreach (XPathNavigator intf in nav.Select("enum")) { | |
100 ProcessEnum(intf, o); | |
101 } | |
102 o.WriteLine("}"); | |
103 } | |
104 static void ProcessEnum(XPathNavigator nav, TextWriter o) { | |
105 String typeName = nav.SelectSingleNode("@name").Value; | |
106 if (!Types.ContainsKey(typeName)) Types.Add(typeName, new TypeInfo(typeName)); | |
107 o.WriteLine("[Guid(\"{0}\")]", nav.SelectSingleNode("@uuid").Value); | |
108 o.WriteLine("enum " + typeName + " {"); | |
109 foreach (XPathNavigator member in nav.SelectChildren(XPathNodeType.Element)) { | |
110 switch (member.Name) { | |
111 case "desc": | |
112 break; | |
113 case "const": | |
114 o.WriteLine("\t{0} = {1},", member.SelectSingleNode("@name").Value, member.SelectSingleNode("@value").Value); | |
115 break; | |
116 default: | |
117 Console.Error.WriteLine("Unknown member type {0}", member.Name); | |
118 break; | |
119 } | |
120 } | |
121 o.WriteLine("}"); | |
122 } | |
123 static void ProcessInterface(XPathNavigator nav, TextWriter o, XPathNavigator parentNav) { | |
124 String typeName = nav.SelectSingleNode("@name").Value; | |
125 if (!Types.ContainsKey(typeName)) Types.Add(typeName, new TypeInfo(typeName, "MarshalAs(UnmanagedType.Interface)")); | |
126 o.WriteLine("[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]"); | |
127 o.WriteLine("[Guid(\"{0}\")]", nav.SelectSingleNode("@uuid").Value); | |
128 o.WriteLine("[ComImport()]"); | |
129 o.Write("interface " + typeName); | |
130 o.WriteLine(" {"); | |
131 ProcessInterfaceMembersAndInherited(nav, o, parentNav); | |
132 o.WriteLine("}"); | |
133 } | |
134 static void ProcessInterfaceMembersAndInherited(XPathNavigator nav, TextWriter o, XPathNavigator parentNav) { | |
135 XPathItem item = nav.SelectSingleNode("@extends"); | |
136 if (item != null && item.Value[0] != '$') { | |
137 XPathNavigator inav = parentNav.SelectSingleNode("interface[@name='" + item.Value + "']"); | |
138 ProcessInterfaceMembersAndInherited(inav, o, parentNav); | |
139 } | |
140 ProcessInterfaceMembers(nav.SelectChildren(XPathNodeType.Element), o); | |
141 } | |
142 static void ProcessInterfaceMembers(XPathNodeIterator members, TextWriter oattribute) { | |
143 XPathItem item; | |
144 StringWriter omethod = new StringWriter(); | |
145 foreach (XPathNavigator member in members) { | |
146 switch (member.Name) { | |
147 case "desc": | |
148 break; | |
149 case "attribute": { | |
150 String mName = member.SelectSingleNode("@name").Value; | |
151 item = member.SelectSingleNode("@readonly"); | |
152 Boolean mReadOnly = item == null ? false : item.Value == "yes"; | |
153 mName = mName.Substring(0, 1).ToUpper() + mName.Substring(1); | |
154 oattribute.Write("\t"); | |
155 TypeInfo t = GetTypeDeclaration(member); | |
156 oattribute.Write(t.Name); | |
157 oattribute.Write(" "); | |
158 oattribute.Write(mName); | |
159 oattribute.WriteLine(" {"); | |
160 oattribute.Write("\t\t[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] "); | |
161 t.WriteAttributes(oattribute, ParameterType.Return); | |
162 oattribute.WriteLine("get;"); | |
163 if (!mReadOnly) { | |
164 oattribute.Write("\t\t[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] "); | |
165 t.WriteAttributes(oattribute, ParameterType.Param); | |
166 oattribute.WriteLine("set;"); | |
167 } | |
168 oattribute.WriteLine("\t}"); | |
169 } break; | |
170 case "method": { | |
171 String mName = member.SelectSingleNode("@name").Value; | |
172 XPathNodeIterator mParamReturn = member.Select("param[@dir='return']"); | |
173 omethod.WriteLine("\t[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]"); | |
174 omethod.Write("\t"); | |
175 bool mReturn = false; | |
176 if (mParamReturn == null || mParamReturn.Count != 1) { | |
177 omethod.Write("void"); | |
178 } else { | |
179 mParamReturn.MoveNext(); | |
180 mReturn = true; | |
2
f1deea9c97a0
Cleaned up the interop code generator, added wrapper application to initialize kernel driver and run mono
Ivo Smits
parents:
0
diff
changeset
|
181 WriteTypeDeclaration(omethod, mParamReturn.Current, ParameterType.Return); |
0 | 182 } |
183 mName = mName.Substring(0, 1).ToUpper() + mName.Substring(1); | |
184 omethod.Write(" "); | |
185 omethod.Write(mName); | |
186 omethod.Write("("); | |
187 XPathNodeIterator mParams = member.Select("param"); | |
188 bool first = true; | |
189 if (mParams.MoveNext()) { | |
190 while (true) { | |
191 XPathNavigator mParam = mParams.Current; | |
192 String pDir = mParam.SelectSingleNode("@dir").Value; | |
193 if (pDir == "return" && mReturn) { | |
194 if (mParams.MoveNext()) { | |
195 continue; | |
196 } else { | |
197 break; | |
198 } | |
199 } else if (pDir == "in") { | |
200 } else if (pDir == "out") { | |
201 } else { | |
202 Console.Error.WriteLine("Unsupported parameter direction {0}", pDir); | |
203 } | |
204 if (first) { | |
205 first = false; | |
206 } else { | |
207 omethod.Write(", "); | |
208 } | |
2
f1deea9c97a0
Cleaned up the interop code generator, added wrapper application to initialize kernel driver and run mono
Ivo Smits
parents:
0
diff
changeset
|
209 WriteTypeDeclaration(omethod, mParam, pDir == "out" ? ParameterType.Out : ParameterType.In); |
0 | 210 omethod.Write(" p"); |
211 omethod.Write(mParam.SelectSingleNode("@name").Value); | |
212 if (!mParams.MoveNext()) break; | |
213 } | |
214 } | |
215 omethod.WriteLine(");"); | |
216 } break; | |
217 default: | |
218 Console.Error.WriteLine("Unknown member type {0}", member.Name); | |
219 break; | |
220 } | |
221 } | |
222 oattribute.Write((omethod as StringWriter).ToString()); | |
223 } | |
224 private static TypeInfo GetTypeDeclaration(XPathNavigator nav) { | |
225 ParameterType pt = ParameterType.Param; | |
226 return GetTypeDeclaration(nav, ref pt); | |
227 } | |
2
f1deea9c97a0
Cleaned up the interop code generator, added wrapper application to initialize kernel driver and run mono
Ivo Smits
parents:
0
diff
changeset
|
228 private static void WriteTypeDeclaration(TextWriter o, XPathNavigator nav, ParameterType paramType) { |
f1deea9c97a0
Cleaned up the interop code generator, added wrapper application to initialize kernel driver and run mono
Ivo Smits
parents:
0
diff
changeset
|
229 TypeInfo t = GetTypeDeclaration(nav, ref paramType); |
f1deea9c97a0
Cleaned up the interop code generator, added wrapper application to initialize kernel driver and run mono
Ivo Smits
parents:
0
diff
changeset
|
230 t.WriteDeclaration(o, paramType); |
f1deea9c97a0
Cleaned up the interop code generator, added wrapper application to initialize kernel driver and run mono
Ivo Smits
parents:
0
diff
changeset
|
231 } |
0 | 232 private static TypeInfo GetTypeDeclaration(XPathNavigator nav, ref ParameterType paramType) { |
233 String mType = nav.SelectSingleNode("@type").Value; | |
234 XPathItem item; | |
235 item = nav.SelectSingleNode("@mod"); | |
236 String mMod = item == null ? null : item.Value; | |
237 item = nav.SelectSingleNode("@safearray"); | |
238 Boolean pArray = item == null ? false : item.Value == "yes"; | |
239 | |
240 TypeInfo t; | |
241 if (!Types.TryGetValue(mType, out t)) { | |
242 Console.Error.WriteLine("Type {0} is not supported", mType); | |
243 t = new TypeInfo("void"); | |
244 } | |
245 if (mMod == "ptr") { | |
246 if (paramType == ParameterType.In) { | |
247 paramType = ParameterType.Reference; | |
248 } else { | |
249 t = new TypeInfo("IntPtr"); | |
250 } | |
251 } else if (mMod == "string") { | |
252 t = new TypeInfo("String", "MarshalAs(UnmanagedType.LPWStr)"); | |
253 } else if (mMod != null) { | |
254 Console.Error.WriteLine("Type modifier {0} is not supported", mMod); | |
255 t = new TypeInfo("void"); | |
256 } | |
257 if (pArray) { | |
258 t = new TypeInfo("Array", "MarshalAs(UnmanagedType.SafeArray)"); | |
259 if (paramType == ParameterType.In || paramType == ParameterType.Out) paramType = ParameterType.Reference; | |
260 } | |
261 return t; | |
262 } | |
263 } |