annotate InteropCodeGen/gendotnet.cs @ 4:64226294e26b

Added some information on using the interop interface generator
author Ivo Smits
date Wed, 04 May 2011 21:15:22 +0200
parents f1deea9c97a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4
64226294e26b Added some information on using the interop interface generator
Ivo Smits
parents: 2
diff changeset
1 /* This script can be used to generate C# interface definitions for XPCOM
64226294e26b Added some information on using the interop interface generator
Ivo Smits
parents: 2
diff changeset
2 * interop, based on an xidl file. It is currently not very flexible and
64226294e26b Added some information on using the interop interface generator
Ivo Smits
parents: 2
diff changeset
3 * biased towards VirtualBox.
64226294e26b Added some information on using the interop interface generator
Ivo Smits
parents: 2
diff changeset
4 *
64226294e26b Added some information on using the interop interface generator
Ivo Smits
parents: 2
diff changeset
5 * To use, put the appropriate VirtualBox.xidl file in the same directory as
64226294e26b Added some information on using the interop interface generator
Ivo Smits
parents: 2
diff changeset
6 * the application, and run it while piping it's output to a file:
64226294e26b Added some information on using the interop interface generator
Ivo Smits
parents: 2
diff changeset
7 * mono InteropCodeGen.exe > VirtualBox.cs
64226294e26b Added some information on using the interop interface generator
Ivo Smits
parents: 2
diff changeset
8 * Then, for compatibility with the interop assembly generated by VS.Net, a
64226294e26b Added some information on using the interop interface generator
Ivo Smits
parents: 2
diff changeset
9 * few modifications need to be made using the following regular expressions:
64226294e26b Added some information on using the interop interface generator
Ivo Smits
parents: 2
diff changeset
10 * sed -i VirtualBox.cs "s/void LockMachine(\[MarshalAs(UnmanagedType.Interface)\] ISession psession, LockType plockType);/void LockMachine([MarshalAs(UnmanagedType.Interface)\] Session psession, LockType plockType);/"
64226294e26b Added some information on using the interop interface generator
Ivo Smits
parents: 2
diff changeset
11 * sed -i VirtualBox.cs "s/LaunchVMProcess(\[MarshalAs(UnmanagedType\.Interface)\] ISession psession,/LaunchVMProcess([MarshalAs(UnmanagedType.Interface)] Session psession,/"
64226294e26b Added some information on using the interop interface generator
Ivo Smits
parents: 2
diff changeset
12 * sed -i VirtualBox.cs "s/\(interface IVirtualBoxErrorInfo {\)/\1\n\tvoid dummy1();void dummy2();void dummy3();void dummy4();void dummy5(); void dummy6(); void dummy7(); void dummy8(); void dummy9(); void dummy10();/"
64226294e26b Added some information on using the interop interface generator
Ivo Smits
parents: 2
diff changeset
13 * Then, a few lines need to be appended to the file:
64226294e26b Added some information on using the interop interface generator
Ivo Smits
parents: 2
diff changeset
14 * namespace VirtualBox {
64226294e26b Added some information on using the interop interface generator
Ivo Smits
parents: 2
diff changeset
15 * [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)][Guid("12F4DCDB-12B2-4EC1-B7CD-DDD9F6C5BF4D")][ComImport()]interface Session : ISession {}
64226294e26b Added some information on using the interop interface generator
Ivo Smits
parents: 2
diff changeset
16 * }
64226294e26b Added some information on using the interop interface generator
Ivo Smits
parents: 2
diff changeset
17 * Then, compile the generated file:
64226294e26b Added some information on using the interop interface generator
Ivo Smits
parents: 2
diff changeset
18 * gmcs -target:library -out:Interop.VirtualBox.XPCOM.dll VirtualBox.cs
64226294e26b Added some information on using the interop interface generator
Ivo Smits
parents: 2
diff changeset
19 */
0
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
20 //+reference System.dll
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
21 //+reference System.Xml.dll
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
22 using System;
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
23 using System.Xml.XPath;
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
24 using System.IO;
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
25 using System.Collections.Generic;
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
26 class Program {
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
27 enum ParameterType {
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
28 In,
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
29 Out,
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
30 Reference,
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
31 Return,
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
32 Param,
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
33 }
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
34 class TypeInfo {
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
35 public String Name { get; private set; }
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
36 public String[] Attributes { get; private set; }
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
37
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
38 public TypeInfo(String name, params String[] attributes) {
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
39 this.Name = name;
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
40 this.Attributes = attributes;
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
41 }
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
42 public void WriteDeclaration(TextWriter o, ParameterType vartype) {
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
43 WriteAttributes(o, vartype);
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
44 o.Write(Name);
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
45 }
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
46 public void WriteAttributes(TextWriter o, ParameterType vartype) {
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
47 foreach (String attribute in Attributes) {
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
48 o.Write("[");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
49 if (vartype == ParameterType.Return) o.Write("return: ");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
50 else if (vartype == ParameterType.Param) o.Write("param: ");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
51 o.Write(attribute);
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
52 o.Write("] ");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
53 }
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
54 if (vartype == ParameterType.Out) o.Write("out ");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
55 else if (vartype == ParameterType.Reference) o.Write("ref ");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
56 }
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
57 }
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
58 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
59 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
60 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
61 }
f1deea9c97a0 Cleaned up the interop code generator, added wrapper application to initialize kernel driver and run mono
Ivo Smits
parents: 0
diff changeset
62 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
63 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
64 }
0
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
65 static void InitTypes() {
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
66 Types.Add("short", new TypeInfo("Int16"));
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
67 Types.Add("unsigned short", new TypeInfo("UInt16"));
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
68 Types.Add("unsigned long", new TypeInfo("UInt32"));
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
69 Types.Add("long long", new TypeInfo("Int64"));
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
70 Types.Add("long", new TypeInfo("Int32"));
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
71 Types.Add("octet", new TypeInfo("Byte"));
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
72 Types.Add("unsigned long long", new TypeInfo("UInt32"));
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
73 //Types.Add("boolean", new TypeInfo("Boolean", "MarshalAs(UnmanagedType.Bool)"));
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
74 Types.Add("boolean", new TypeInfo("Int32"));
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
75 Types.Add("wstring", new TypeInfo("String", "MarshalAs(UnmanagedType.LPWStr)"));
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
76 //Types.Add("uuid", new TypeInfo("Guid", true, "MarshalAs(UnmanagedType.LPStruct)"));
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
77 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
78 Types.Add("$unknown", new TypeInfo("IntPtr"));
0
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
79
2
f1deea9c97a0 Cleaned up the interop code generator, added wrapper application to initialize kernel driver and run mono
Ivo Smits
parents: 0
diff changeset
80 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
81 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
82 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
83 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
84 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
85 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
86 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
87 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
88 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
89 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
90 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
91 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
92
f1deea9c97a0 Cleaned up the interop code generator, added wrapper application to initialize kernel driver and run mono
Ivo Smits
parents: 0
diff changeset
93 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
94 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
95 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
96 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
97 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
98 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
99 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
100 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
101 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
102 AddEnumTypes("AdditionsFacilityStatus", "AdditionsFacilityType", "AdditionsFacilityClass", "CleanupMode", "DataType");
0
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
103 }
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
104 static void Main(string[] args) {
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
105 InitTypes();
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
106
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
107 XPathDocument doc = new XPathDocument("VirtualBox.xidl");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
108 XPathNavigator nav = doc.CreateNavigator();
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
109 nav = nav.SelectSingleNode("/idl/library[@name='VirtualBox']");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
110 TextWriter o = Console.Out;
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
111 o.WriteLine("using System;");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
112 o.WriteLine("using System.Runtime.CompilerServices;");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
113 o.WriteLine("using System.Runtime.InteropServices;");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
114 o.WriteLine("namespace VirtualBox {");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
115 foreach (XPathNavigator intf in nav.Select("interface")) {
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
116 ProcessInterface(intf, o, nav);
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
117 }
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
118 foreach (XPathNavigator intf in nav.Select("enum")) {
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
119 ProcessEnum(intf, o);
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
120 }
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
121 o.WriteLine("}");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
122 }
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
123 static void ProcessEnum(XPathNavigator nav, TextWriter o) {
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
124 String typeName = nav.SelectSingleNode("@name").Value;
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
125 if (!Types.ContainsKey(typeName)) Types.Add(typeName, new TypeInfo(typeName));
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
126 o.WriteLine("[Guid(\"{0}\")]", nav.SelectSingleNode("@uuid").Value);
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
127 o.WriteLine("enum " + typeName + " {");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
128 foreach (XPathNavigator member in nav.SelectChildren(XPathNodeType.Element)) {
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
129 switch (member.Name) {
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
130 case "desc":
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
131 break;
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
132 case "const":
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
133 o.WriteLine("\t{0} = {1},", member.SelectSingleNode("@name").Value, member.SelectSingleNode("@value").Value);
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
134 break;
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
135 default:
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
136 Console.Error.WriteLine("Unknown member type {0}", member.Name);
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
137 break;
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
138 }
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
139 }
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
140 o.WriteLine("}");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
141 }
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
142 static void ProcessInterface(XPathNavigator nav, TextWriter o, XPathNavigator parentNav) {
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
143 String typeName = nav.SelectSingleNode("@name").Value;
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
144 if (!Types.ContainsKey(typeName)) Types.Add(typeName, new TypeInfo(typeName, "MarshalAs(UnmanagedType.Interface)"));
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
145 o.WriteLine("[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
146 o.WriteLine("[Guid(\"{0}\")]", nav.SelectSingleNode("@uuid").Value);
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
147 o.WriteLine("[ComImport()]");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
148 o.Write("interface " + typeName);
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
149 o.WriteLine(" {");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
150 ProcessInterfaceMembersAndInherited(nav, o, parentNav);
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
151 o.WriteLine("}");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
152 }
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
153 static void ProcessInterfaceMembersAndInherited(XPathNavigator nav, TextWriter o, XPathNavigator parentNav) {
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
154 XPathItem item = nav.SelectSingleNode("@extends");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
155 if (item != null && item.Value[0] != '$') {
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
156 XPathNavigator inav = parentNav.SelectSingleNode("interface[@name='" + item.Value + "']");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
157 ProcessInterfaceMembersAndInherited(inav, o, parentNav);
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
158 }
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
159 ProcessInterfaceMembers(nav.SelectChildren(XPathNodeType.Element), o);
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
160 }
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
161 static void ProcessInterfaceMembers(XPathNodeIterator members, TextWriter oattribute) {
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
162 XPathItem item;
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
163 StringWriter omethod = new StringWriter();
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
164 foreach (XPathNavigator member in members) {
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
165 switch (member.Name) {
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
166 case "desc":
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
167 break;
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
168 case "attribute": {
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
169 String mName = member.SelectSingleNode("@name").Value;
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
170 item = member.SelectSingleNode("@readonly");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
171 Boolean mReadOnly = item == null ? false : item.Value == "yes";
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
172 mName = mName.Substring(0, 1).ToUpper() + mName.Substring(1);
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
173 oattribute.Write("\t");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
174 TypeInfo t = GetTypeDeclaration(member);
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
175 oattribute.Write(t.Name);
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
176 oattribute.Write(" ");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
177 oattribute.Write(mName);
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
178 oattribute.WriteLine(" {");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
179 oattribute.Write("\t\t[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] ");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
180 t.WriteAttributes(oattribute, ParameterType.Return);
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
181 oattribute.WriteLine("get;");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
182 if (!mReadOnly) {
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
183 oattribute.Write("\t\t[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] ");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
184 t.WriteAttributes(oattribute, ParameterType.Param);
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
185 oattribute.WriteLine("set;");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
186 }
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
187 oattribute.WriteLine("\t}");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
188 } break;
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
189 case "method": {
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
190 String mName = member.SelectSingleNode("@name").Value;
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
191 XPathNodeIterator mParamReturn = member.Select("param[@dir='return']");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
192 omethod.WriteLine("\t[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
193 omethod.Write("\t");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
194 bool mReturn = false;
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
195 if (mParamReturn == null || mParamReturn.Count != 1) {
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
196 omethod.Write("void");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
197 } else {
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
198 mParamReturn.MoveNext();
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
199 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
200 WriteTypeDeclaration(omethod, mParamReturn.Current, ParameterType.Return);
0
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
201 }
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
202 mName = mName.Substring(0, 1).ToUpper() + mName.Substring(1);
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
203 omethod.Write(" ");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
204 omethod.Write(mName);
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
205 omethod.Write("(");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
206 XPathNodeIterator mParams = member.Select("param");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
207 bool first = true;
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
208 if (mParams.MoveNext()) {
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
209 while (true) {
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
210 XPathNavigator mParam = mParams.Current;
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
211 String pDir = mParam.SelectSingleNode("@dir").Value;
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
212 if (pDir == "return" && mReturn) {
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
213 if (mParams.MoveNext()) {
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
214 continue;
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
215 } else {
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
216 break;
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
217 }
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
218 } else if (pDir == "in") {
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
219 } else if (pDir == "out") {
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
220 } else {
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
221 Console.Error.WriteLine("Unsupported parameter direction {0}", pDir);
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
222 }
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
223 if (first) {
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
224 first = false;
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
225 } else {
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
226 omethod.Write(", ");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
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 WriteTypeDeclaration(omethod, mParam, pDir == "out" ? ParameterType.Out : ParameterType.In);
0
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
229 omethod.Write(" p");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
230 omethod.Write(mParam.SelectSingleNode("@name").Value);
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
231 if (!mParams.MoveNext()) break;
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
232 }
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
233 }
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
234 omethod.WriteLine(");");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
235 } break;
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
236 default:
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
237 Console.Error.WriteLine("Unknown member type {0}", member.Name);
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
238 break;
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
239 }
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
240 }
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
241 oattribute.Write((omethod as StringWriter).ToString());
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
242 }
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
243 private static TypeInfo GetTypeDeclaration(XPathNavigator nav) {
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
244 ParameterType pt = ParameterType.Param;
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
245 return GetTypeDeclaration(nav, ref pt);
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
246 }
2
f1deea9c97a0 Cleaned up the interop code generator, added wrapper application to initialize kernel driver and run mono
Ivo Smits
parents: 0
diff changeset
247 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
248 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
249 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
250 }
0
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
251 private static TypeInfo GetTypeDeclaration(XPathNavigator nav, ref ParameterType paramType) {
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
252 String mType = nav.SelectSingleNode("@type").Value;
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
253 XPathItem item;
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
254 item = nav.SelectSingleNode("@mod");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
255 String mMod = item == null ? null : item.Value;
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
256 item = nav.SelectSingleNode("@safearray");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
257 Boolean pArray = item == null ? false : item.Value == "yes";
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
258
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
259 TypeInfo t;
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
260 if (!Types.TryGetValue(mType, out t)) {
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
261 Console.Error.WriteLine("Type {0} is not supported", mType);
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
262 t = new TypeInfo("void");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
263 }
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
264 if (mMod == "ptr") {
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
265 if (paramType == ParameterType.In) {
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
266 paramType = ParameterType.Reference;
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
267 } else {
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
268 t = new TypeInfo("IntPtr");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
269 }
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
270 } else if (mMod == "string") {
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
271 t = new TypeInfo("String", "MarshalAs(UnmanagedType.LPWStr)");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
272 } else if (mMod != null) {
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
273 Console.Error.WriteLine("Type modifier {0} is not supported", mMod);
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
274 t = new TypeInfo("void");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
275 }
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
276 if (pArray) {
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
277 t = new TypeInfo("Array", "MarshalAs(UnmanagedType.SafeArray)");
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
278 if (paramType == ParameterType.In || paramType == ParameterType.Out) paramType = ParameterType.Reference;
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
279 }
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
280 return t;
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
281 }
e1ec7bf71313 Initial commit
Ivo Smits
parents:
diff changeset
282 }