comparison InteropCodeGen/gendotnet.cs @ 0:e1ec7bf71313

Initial commit
author Ivo Smits
date Wed, 04 May 2011 00:59:43 +0200
parents
children f1deea9c97a0
comparison
equal deleted inserted replaced
-1:000000000000 0:e1ec7bf71313
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 //public Boolean InputOnly { get; private set; }
19 public String Members { get; set; }
20
21 public TypeInfo(String name, params String[] attributes) {
22 this.Name = name;
23 this.Attributes = attributes;
24 }
25 /*public TypeInfo(String name, bool inputOnly, params String[] attributes)
26 : this(name, attributes) {
27 this.InputOnly = inputOnly;
28 }*/
29 /*public static TypeInfo CreateInterfaceWithMembers(String name, String members) {
30 TypeInfo ret = new TypeInfo(name, "MarshalAs(UnmanagedType.Interface)");
31 ret.Members = members;
32 return ret;
33 }*/
34 //Todo: if attribute mod="string"/"ptr" ...
35 public void WriteDeclaration(TextWriter o, ParameterType vartype) {
36 WriteAttributes(o, vartype);
37 o.Write(Name);
38 }
39 public void WriteAttributes(TextWriter o, ParameterType vartype) {
40 //if (InputOnly && vartype != ParameterType.In) {
41 foreach (String attribute in Attributes) {
42 o.Write("[");
43 if (vartype == ParameterType.Return) o.Write("return: ");
44 else if (vartype == ParameterType.Param) o.Write("param: ");
45 o.Write(attribute);
46 o.Write("] ");
47 }
48 if (vartype == ParameterType.Out) o.Write("out ");
49 else if (vartype == ParameterType.Reference) o.Write("ref ");
50 }
51 }
52 static Dictionary<String, TypeInfo> Types = new Dictionary<string, TypeInfo>();
53 static void InitTypes() {
54 Types.Add("short", new TypeInfo("Int16"));
55 Types.Add("unsigned short", new TypeInfo("UInt16"));
56 Types.Add("unsigned long", new TypeInfo("UInt32"));
57 Types.Add("long long", new TypeInfo("Int64"));
58 Types.Add("long", new TypeInfo("Int32"));
59 Types.Add("octet", new TypeInfo("Byte"));
60 Types.Add("unsigned long long", new TypeInfo("UInt32"));
61 //Types.Add("boolean", new TypeInfo("Boolean", "MarshalAs(UnmanagedType.Bool)"));
62 Types.Add("boolean", new TypeInfo("Int32"));
63 Types.Add("wstring", new TypeInfo("String", "MarshalAs(UnmanagedType.LPWStr)"));
64 //Types.Add("uuid", new TypeInfo("Guid", true, "MarshalAs(UnmanagedType.LPStruct)"));
65 Types.Add("uuid", new TypeInfo("Guid", "MarshalAs(UnmanagedType.LPStruct)"));
66
67 Types.Add("IMachine", new TypeInfo("IMachine", "MarshalAs(UnmanagedType.Interface)"));
68 Types.Add("ISession", new TypeInfo("ISession", "MarshalAs(UnmanagedType.Interface)"));
69 Types.Add("IVirtualBox", new TypeInfo("IVirtualBox", "MarshalAs(UnmanagedType.Interface)"));
70 Types.Add("IHost", new TypeInfo("IHost", "MarshalAs(UnmanagedType.Interface)"));
71 Types.Add("IConsole", new TypeInfo("IConsole", "MarshalAs(UnmanagedType.Interface)"));
72 Types.Add("ISystemProperties", new TypeInfo("ISystemProperties", "MarshalAs(UnmanagedType.Interface)"));
73 Types.Add("IProgress", new TypeInfo("IProgress", "MarshalAs(UnmanagedType.Interface)"));
74 Types.Add("IDisplay", new TypeInfo("IDisplay", "MarshalAs(UnmanagedType.Interface)"));
75 Types.Add("IMouse", new TypeInfo("IMouse", "MarshalAs(UnmanagedType.Interface)"));
76 Types.Add("IKeyboard", new TypeInfo("IKeyboard", "MarshalAs(UnmanagedType.Interface)"));
77 Types.Add("IFramebuffer", new TypeInfo("IFramebuffer", "MarshalAs(UnmanagedType.Interface)"));
78 Types.Add("IFramebufferOverlay", new TypeInfo("IFramebufferOverlay", "MarshalAs(UnmanagedType.Interface)"));
79 Types.Add("IMachineDebugger", new TypeInfo("IMachineDebugger", "MarshalAs(UnmanagedType.Interface)"));
80 Types.Add("IVirtualBoxErrorInfo", new TypeInfo("IVirtualBoxErrorInfo", "MarshalAs(UnmanagedType.Interface)"));
81 Types.Add("IEventSource", new TypeInfo("IEventSource", "MarshalAs(UnmanagedType.Interface)"));
82 Types.Add("IEventListener", new TypeInfo("IEventListener", "MarshalAs(UnmanagedType.Interface)"));
83 Types.Add("IEventContext", new TypeInfo("IEventContext", "MarshalAs(UnmanagedType.Interface)"));
84 Types.Add("IConsoleCallback", new TypeInfo("IConsoleCallback", "MarshalAs(UnmanagedType.Interface)"));
85 Types.Add("IEvent", new TypeInfo("IEvent", "MarshalAs(UnmanagedType.Interface)"));
86
87 Types.Add("LockType", new TypeInfo("LockType"));
88 Types.Add("MediumVariant", new TypeInfo("MediumVariant"));
89 Types.Add("AccessMode", new TypeInfo("AccessMode"));
90 Types.Add("NATProtocol", new TypeInfo("NATProtocol"));
91 Types.Add("FirmwareType", new TypeInfo("FirmwareType"));
92 Types.Add("StorageControllerType", new TypeInfo("StorageControllerType"));
93 Types.Add("StorageBus", new TypeInfo("StorageBus"));
94 Types.Add("SessionType", new TypeInfo("SessionType"));
95 Types.Add("SessionState", new TypeInfo("SessionState"));
96 Types.Add("USBDeviceState", new TypeInfo("USBDeviceState"));
97 Types.Add("USBDeviceFilterAction", new TypeInfo("USBDeviceFilterAction"));
98 Types.Add("AudioControllerType", new TypeInfo("AudioControllerType"));
99 Types.Add("AudioDriverType", new TypeInfo("AudioDriverType"));
100 Types.Add("VRDPAuthType", new TypeInfo("VRDPAuthType"));
101 Types.Add("MachineState", new TypeInfo("MachineState"));
102 Types.Add("NetworkAdapterType", new TypeInfo("NetworkAdapterType"));
103 Types.Add("NetworkAttachmentType", new TypeInfo("NetworkAttachmentType"));
104 Types.Add("PortMode", new TypeInfo("PortMode"));
105 Types.Add("DeviceType", new TypeInfo("DeviceType"));
106 Types.Add("MediumState", new TypeInfo("MediumState"));
107 Types.Add("MediumType", new TypeInfo("MediumType"));
108 Types.Add("HostNetworkInterfaceType", new TypeInfo("HostNetworkInterfaceType"));
109 Types.Add("DeviceActivity", new TypeInfo("DeviceActivity"));
110 Types.Add("HostNetworkInterfaceMediumType", new TypeInfo("HostNetworkInterfaceMediumType"));
111 Types.Add("HostNetworkInterfaceStatus", new TypeInfo("HostNetworkInterfaceStatus"));
112 Types.Add("ProcessorFeature", new TypeInfo("ProcessorFeature"));
113 Types.Add("VFSType", new TypeInfo("VFSType"));
114 Types.Add("BIOSBootMenuMode", new TypeInfo("BIOSBootMenuMode"));
115 Types.Add("VirtualSystemDescriptionType", new TypeInfo("VirtualSystemDescriptionType"));
116 Types.Add("VirtualSystemDescriptionValueType", new TypeInfo("VirtualSystemDescriptionValueType"));
117 Types.Add("KeyboardHidType", new TypeInfo("KeyboardHidType"));
118 Types.Add("ClipboardMode", new TypeInfo("ClipboardMode"));
119 Types.Add("PointingHidType", new TypeInfo("PointingHidType"));
120 Types.Add("CPUPropertyType", new TypeInfo("CPUPropertyType"));
121 Types.Add("HWVirtExPropertyType", new TypeInfo("HWVirtExPropertyType"));
122 Types.Add("Scope", new TypeInfo("Scope"));
123 Types.Add("ChipsetType", new TypeInfo("ChipsetType"));
124 Types.Add("FaultToleranceState", new TypeInfo("FaultToleranceState"));
125 Types.Add("BandwidthGroupType", new TypeInfo("BandwidthGroupType"));
126 Types.Add("VBoxEventType", new TypeInfo("VBoxEventType"));
127 Types.Add("GuestMonitorChangedEventType", new TypeInfo("GuestMonitorChangedEventType"));
128 Types.Add("AuthType", new TypeInfo("AuthType"));
129 Types.Add("NetworkAdapterPromiscModePolicy", new TypeInfo("NetworkAdapterPromiscModePolicy"));
130 Types.Add("ExecuteProcessStatus", new TypeInfo("ExecuteProcessStatus"));
131 Types.Add("AdditionsRunLevelType", new TypeInfo("AdditionsRunLevelType"));
132 Types.Add("AdditionsFacilityStatus", new TypeInfo("AdditionsFacilityStatus"));
133 Types.Add("AdditionsFacilityType", new TypeInfo("AdditionsFacilityType"));
134 Types.Add("AdditionsFacilityClass", new TypeInfo("AdditionsFacilityClass"));
135 Types.Add("CleanupMode", new TypeInfo("CleanupMode"));
136 Types.Add("DataType", new TypeInfo("DataType"));
137
138 Types.Add("IBandwidthControl", new TypeInfo("IntPtr"));
139 Types.Add("IVRDEServerInfo", new TypeInfo("IntPtr"));
140 Types.Add("IAdditionsFacility", new TypeInfo("IntPtr"));
141 Types.Add("IExtPackPlugIn", new TypeInfo("IntPtr"));
142 Types.Add("IExtPackFile", new TypeInfo("IntPtr"));
143 Types.Add("IExtPack", new TypeInfo("IntPtr"));
144 Types.Add("IBIOSSettings", new TypeInfo("IntPtr"));
145 Types.Add("IVFSExplorer", new TypeInfo("IntPtr"));
146 Types.Add("IUSBController", new TypeInfo("IntPtr"));
147 Types.Add("IStorageController", new TypeInfo("IntPtr"));
148 Types.Add("IVRDPServer", new TypeInfo("IntPtr"));
149 Types.Add("ISnapshot", new TypeInfo("IntPtr"));
150 Types.Add("INATEngine", new TypeInfo("IntPtr"));
151 Types.Add("IUSBDeviceFilter", new TypeInfo("IntPtr"));
152 Types.Add("IMediumAttachment", new TypeInfo("IntPtr"));
153 Types.Add("IUSBDevice", new TypeInfo("IntPtr"));
154 Types.Add("IParallelPort", new TypeInfo("IntPtr"));
155 Types.Add("ISerialPort", new TypeInfo("IntPtr"));
156 Types.Add("INetworkAdapter", new TypeInfo("IntPtr"));
157 Types.Add("IMedium", new TypeInfo("IntPtr"));
158 Types.Add("IGuestOSType", new TypeInfo("IntPtr"));
159 Types.Add("ISharedFolder", new TypeInfo("IntPtr"));
160 Types.Add("IPerformanceCollector", new TypeInfo("IntPtr"));
161 Types.Add("IDHCPServer", new TypeInfo("IntPtr"));
162 Types.Add("IAppliance", new TypeInfo("IntPtr"));
163 Types.Add("IVirtualBoxCallback", new TypeInfo("IntPtr"));
164 Types.Add("IPerformanceMetric", new TypeInfo("IntPtr"));
165 Types.Add("IMediumFormat", new TypeInfo("IntPtr"));
166 Types.Add("IHostUSBDevice", new TypeInfo("IntPtr"));
167 Types.Add("IHostNetworkInterface", new TypeInfo("IntPtr"));
168 Types.Add("IHostUSBDeviceFilter", new TypeInfo("IntPtr"));
169 Types.Add("IRemoteDisplayInfo", new TypeInfo("IntPtr"));
170 Types.Add("IGuest", new TypeInfo("IntPtr"));
171 Types.Add("IVirtualSystemDescription", new TypeInfo("IntPtr"));
172 Types.Add("IAudioAdapter", new TypeInfo("IntPtr"));
173 Types.Add("IExtPackManager", new TypeInfo("IntPtr"));
174 Types.Add("IVRDEServer", new TypeInfo("IntPtr"));
175 Types.Add("IPciDeviceAttachment", new TypeInfo("IntPtr"));
176 Types.Add("IBandwidthGroup", new TypeInfo("IntPtr"));
177
178 Types.Add("$unknown", new TypeInfo("IntPtr"));
179 }
180 static void Main(string[] args) {
181 InitTypes();
182
183 XPathDocument doc = new XPathDocument("VirtualBox.xidl");
184 XPathNavigator nav = doc.CreateNavigator();
185 nav = nav.SelectSingleNode("/idl/library[@name='VirtualBox']");
186 TextWriter o = Console.Out;
187 o.WriteLine("using System;");
188 o.WriteLine("using System.Runtime.CompilerServices;");
189 o.WriteLine("using System.Runtime.InteropServices;");
190 o.WriteLine("namespace VirtualBox {");
191 foreach (XPathNavigator intf in nav.Select("interface")) {
192 ProcessInterface(intf, o, nav);
193 }
194 foreach (XPathNavigator intf in nav.Select("enum")) {
195 ProcessEnum(intf, o);
196 }
197 o.WriteLine("}");
198 }
199 static void ProcessEnum(XPathNavigator nav, TextWriter o) {
200 String typeName = nav.SelectSingleNode("@name").Value;
201 if (!Types.ContainsKey(typeName)) Types.Add(typeName, new TypeInfo(typeName));
202 o.WriteLine("[Guid(\"{0}\")]", nav.SelectSingleNode("@uuid").Value);
203 o.WriteLine("enum " + typeName + " {");
204 foreach (XPathNavigator member in nav.SelectChildren(XPathNodeType.Element)) {
205 switch (member.Name) {
206 case "desc":
207 break;
208 case "const":
209 o.WriteLine("\t{0} = {1},", member.SelectSingleNode("@name").Value, member.SelectSingleNode("@value").Value);
210 break;
211 default:
212 Console.Error.WriteLine("Unknown member type {0}", member.Name);
213 break;
214 }
215 }
216 o.WriteLine("}");
217 }
218 static void ProcessInterface(XPathNavigator nav, TextWriter o, XPathNavigator parentNav) {
219 String typeName = nav.SelectSingleNode("@name").Value;
220 if (!Types.ContainsKey(typeName)) Types.Add(typeName, new TypeInfo(typeName, "MarshalAs(UnmanagedType.Interface)"));
221 o.WriteLine("[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]");
222 o.WriteLine("[Guid(\"{0}\")]", nav.SelectSingleNode("@uuid").Value);
223 o.WriteLine("[ComImport()]");
224 o.Write("interface " + typeName);
225 o.WriteLine(" {");
226 ProcessInterfaceMembersAndInherited(nav, o, parentNav);
227 o.WriteLine("}");
228 }
229 static void ProcessInterfaceMembersAndInherited(XPathNavigator nav, TextWriter o, XPathNavigator parentNav) {
230 XPathItem item = nav.SelectSingleNode("@extends");
231 if (item != null && item.Value[0] != '$') {
232 XPathNavigator inav = parentNav.SelectSingleNode("interface[@name='" + item.Value + "']");
233 ProcessInterfaceMembersAndInherited(inav, o, parentNav);
234 }
235 ProcessInterfaceMembers(nav.SelectChildren(XPathNodeType.Element), o);
236 }
237 static void ProcessInterfaceMembers(XPathNodeIterator members, TextWriter oattribute) {
238 XPathItem item;
239 StringWriter omethod = new StringWriter();
240 foreach (XPathNavigator member in members) {
241 switch (member.Name) {
242 case "desc":
243 break;
244 case "attribute": {
245 String mName = member.SelectSingleNode("@name").Value;
246 //String mType = member.SelectSingleNode("@type").Value;
247 item = member.SelectSingleNode("@readonly");
248 Boolean mReadOnly = item == null ? false : item.Value == "yes";
249 //item = member.SelectSingleNode("@mod");
250 //String mMod = item == null ? null : item.Value;
251 mName = mName.Substring(0, 1).ToUpper() + mName.Substring(1);
252 oattribute.Write("\t");
253 /*TypeInfo t;
254 if (mMod == "ptr") {
255 t = new TypeInfo("IntPtr");
256 } else if (mMod == "string") {
257 t = new TypeInfo("String", "MarshalAs(UnmanagedType.LPWStr)");
258 } else if (mMod == null) {
259 if (!Types.TryGetValue(mType, out t)) {
260 Console.Error.WriteLine("Type {0} is not supported", mType);
261 t = new TypeInfo("void");
262 }
263 } else {
264 Console.Error.WriteLine("Type modifier {0} is not supported", mMod);
265 t = new TypeInfo("void");
266 }*/
267 TypeInfo t = GetTypeDeclaration(member);
268 oattribute.Write(t.Name);
269 oattribute.Write(" ");
270 oattribute.Write(mName);
271 oattribute.WriteLine(" {");
272 oattribute.Write("\t\t[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] ");
273 t.WriteAttributes(oattribute, ParameterType.Return);
274 oattribute.WriteLine("get;");
275 if (!mReadOnly) {
276 oattribute.Write("\t\t[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] ");
277 t.WriteAttributes(oattribute, ParameterType.Param);
278 oattribute.WriteLine("set;");
279 }
280 oattribute.WriteLine("\t}");
281 } break;
282 case "method": {
283 String mName = member.SelectSingleNode("@name").Value;
284 XPathNodeIterator mParamReturn = member.Select("param[@dir='return']");
285 omethod.WriteLine("\t[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]");
286 omethod.Write("\t");
287 bool mReturn = false;
288 if (mParamReturn == null || mParamReturn.Count != 1) {
289 omethod.Write("void");
290 } else {
291 mParamReturn.MoveNext();
292 mReturn = true;
293 TypeInfo t = GetTypeDeclaration(mParamReturn.Current);
294 /*String mType = mParamReturn.Current.SelectSingleNode("@type").Value;
295 TypeInfo t;
296 if (!Types.TryGetValue(mType, out t)) {
297 Console.Error.WriteLine("Type {0} is not supported", mType);
298 t = new TypeInfo("void");
299 mReturn = false;
300 }*/
301 t.WriteDeclaration(omethod, ParameterType.Return);
302 }
303 mName = mName.Substring(0, 1).ToUpper() + mName.Substring(1);
304 omethod.Write(" ");
305 omethod.Write(mName);
306 omethod.Write("(");
307 XPathNodeIterator mParams = member.Select("param");
308 bool first = true;
309 if (mParams.MoveNext()) {
310 while (true) {
311 XPathNavigator mParam = mParams.Current;
312 String pDir = mParam.SelectSingleNode("@dir").Value;
313 //item = mParam.SelectSingleNode("@safearray");
314 //Boolean pArray = item == null ? false : item.Value == "yes";
315 //item = mParam.SelectSingleNode("@mod");
316 //String pMod = item == null ? null : item.Value;
317 if (pDir == "return" && mReturn) {
318 if (mParams.MoveNext()) {
319 continue;
320 } else {
321 break;
322 }
323 } else if (pDir == "in") {
324 } else if (pDir == "out") {
325 } else {
326 Console.Error.WriteLine("Unsupported parameter direction {0}", pDir);
327 }
328 if (first) {
329 first = false;
330 } else {
331 omethod.Write(", ");
332 }
333 ParameterType pt = ParameterType.In;
334 if (pDir == "out") pt = ParameterType.Out;
335 TypeInfo t = GetTypeDeclaration(mParam, ref pt);
336 t.WriteDeclaration(omethod, pt);
337 /*if (pArray) {
338 omethod.Write("[MarshalAs(UnmanagedType.SafeArray)] ");
339 if (pDir == "out") omethod.Write("out ");
340 else omethod.Write("ref ");
341 omethod.Write("System.Array");
342 } else {
343 String pType = mParam.SelectSingleNode("@type").Value;
344 TypeInfo t;
345 if (!Types.TryGetValue(pType, out t)) {
346 Console.Error.WriteLine("Type {0} is not supported", pType);
347 t = new TypeInfo("IntPtr");
348 mReturn = false;
349 }
350 if (pMod == "ptr") {
351 t.WriteDeclaration(omethod, ParameterType.Reference);
352 } else if (pDir == "out") {
353 t.WriteDeclaration(omethod, ParameterType.Out);
354 } else {
355 t.WriteDeclaration(omethod, ParameterType.In);
356 }
357 }*/
358 omethod.Write(" p");
359 omethod.Write(mParam.SelectSingleNode("@name").Value);
360 if (!mParams.MoveNext()) break;
361 }
362 }
363 omethod.WriteLine(");");
364 } break;
365 default:
366 Console.Error.WriteLine("Unknown member type {0}", member.Name);
367 break;
368 }
369 }
370 oattribute.Write((omethod as StringWriter).ToString());
371 }
372 private static TypeInfo GetTypeDeclaration(XPathNavigator nav) {
373 ParameterType pt = ParameterType.Param;
374 return GetTypeDeclaration(nav, ref pt);
375 }
376 private static TypeInfo GetTypeDeclaration(XPathNavigator nav, ref ParameterType paramType) {
377 String mType = nav.SelectSingleNode("@type").Value;
378 XPathItem item;
379 item = nav.SelectSingleNode("@mod");
380 String mMod = item == null ? null : item.Value;
381 item = nav.SelectSingleNode("@safearray");
382 Boolean pArray = item == null ? false : item.Value == "yes";
383
384 TypeInfo t;
385 if (!Types.TryGetValue(mType, out t)) {
386 Console.Error.WriteLine("Type {0} is not supported", mType);
387 t = new TypeInfo("void");
388 }
389 if (mMod == "ptr") {
390 if (paramType == ParameterType.In) {
391 paramType = ParameterType.Reference;
392 } else {
393 t = new TypeInfo("IntPtr");
394 }
395 } else if (mMod == "string") {
396 t = new TypeInfo("String", "MarshalAs(UnmanagedType.LPWStr)");
397 } else if (mMod != null) {
398 Console.Error.WriteLine("Type modifier {0} is not supported", mMod);
399 t = new TypeInfo("void");
400 }
401 if (pArray) {
402 t = new TypeInfo("Array", "MarshalAs(UnmanagedType.SafeArray)");
403 if (paramType == ParameterType.In || paramType == ParameterType.Out) paramType = ParameterType.Reference;
404 }
405 return t;
406 }
407 }