Mercurial > hg > vboxdotnet
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 |
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 | 20 //+reference System.dll |
21 //+reference System.Xml.dll | |
22 using System; | |
23 using System.Xml.XPath; | |
24 using System.IO; | |
25 using System.Collections.Generic; | |
26 class Program { | |
27 enum ParameterType { | |
28 In, | |
29 Out, | |
30 Reference, | |
31 Return, | |
32 Param, | |
33 } | |
34 class TypeInfo { | |
35 public String Name { get; private set; } | |
36 public String[] Attributes { get; private set; } | |
37 | |
38 public TypeInfo(String name, params String[] attributes) { | |
39 this.Name = name; | |
40 this.Attributes = attributes; | |
41 } | |
42 public void WriteDeclaration(TextWriter o, ParameterType vartype) { | |
43 WriteAttributes(o, vartype); | |
44 o.Write(Name); | |
45 } | |
46 public void WriteAttributes(TextWriter o, ParameterType vartype) { | |
47 foreach (String attribute in Attributes) { | |
48 o.Write("["); | |
49 if (vartype == ParameterType.Return) o.Write("return: "); | |
50 else if (vartype == ParameterType.Param) o.Write("param: "); | |
51 o.Write(attribute); | |
52 o.Write("] "); | |
53 } | |
54 if (vartype == ParameterType.Out) o.Write("out "); | |
55 else if (vartype == ParameterType.Reference) o.Write("ref "); | |
56 } | |
57 } | |
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 | 65 static void InitTypes() { |
66 Types.Add("short", new TypeInfo("Int16")); | |
67 Types.Add("unsigned short", new TypeInfo("UInt16")); | |
68 Types.Add("unsigned long", new TypeInfo("UInt32")); | |
69 Types.Add("long long", new TypeInfo("Int64")); | |
70 Types.Add("long", new TypeInfo("Int32")); | |
71 Types.Add("octet", new TypeInfo("Byte")); | |
72 Types.Add("unsigned long long", new TypeInfo("UInt32")); | |
73 //Types.Add("boolean", new TypeInfo("Boolean", "MarshalAs(UnmanagedType.Bool)")); | |
74 Types.Add("boolean", new TypeInfo("Int32")); | |
75 Types.Add("wstring", new TypeInfo("String", "MarshalAs(UnmanagedType.LPWStr)")); | |
76 //Types.Add("uuid", new TypeInfo("Guid", true, "MarshalAs(UnmanagedType.LPStruct)")); | |
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 | 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 | 103 } |
104 static void Main(string[] args) { | |
105 InitTypes(); | |
106 | |
107 XPathDocument doc = new XPathDocument("VirtualBox.xidl"); | |
108 XPathNavigator nav = doc.CreateNavigator(); | |
109 nav = nav.SelectSingleNode("/idl/library[@name='VirtualBox']"); | |
110 TextWriter o = Console.Out; | |
111 o.WriteLine("using System;"); | |
112 o.WriteLine("using System.Runtime.CompilerServices;"); | |
113 o.WriteLine("using System.Runtime.InteropServices;"); | |
114 o.WriteLine("namespace VirtualBox {"); | |
115 foreach (XPathNavigator intf in nav.Select("interface")) { | |
116 ProcessInterface(intf, o, nav); | |
117 } | |
118 foreach (XPathNavigator intf in nav.Select("enum")) { | |
119 ProcessEnum(intf, o); | |
120 } | |
121 o.WriteLine("}"); | |
122 } | |
123 static void ProcessEnum(XPathNavigator nav, TextWriter o) { | |
124 String typeName = nav.SelectSingleNode("@name").Value; | |
125 if (!Types.ContainsKey(typeName)) Types.Add(typeName, new TypeInfo(typeName)); | |
126 o.WriteLine("[Guid(\"{0}\")]", nav.SelectSingleNode("@uuid").Value); | |
127 o.WriteLine("enum " + typeName + " {"); | |
128 foreach (XPathNavigator member in nav.SelectChildren(XPathNodeType.Element)) { | |
129 switch (member.Name) { | |
130 case "desc": | |
131 break; | |
132 case "const": | |
133 o.WriteLine("\t{0} = {1},", member.SelectSingleNode("@name").Value, member.SelectSingleNode("@value").Value); | |
134 break; | |
135 default: | |
136 Console.Error.WriteLine("Unknown member type {0}", member.Name); | |
137 break; | |
138 } | |
139 } | |
140 o.WriteLine("}"); | |
141 } | |
142 static void ProcessInterface(XPathNavigator nav, TextWriter o, XPathNavigator parentNav) { | |
143 String typeName = nav.SelectSingleNode("@name").Value; | |
144 if (!Types.ContainsKey(typeName)) Types.Add(typeName, new TypeInfo(typeName, "MarshalAs(UnmanagedType.Interface)")); | |
145 o.WriteLine("[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]"); | |
146 o.WriteLine("[Guid(\"{0}\")]", nav.SelectSingleNode("@uuid").Value); | |
147 o.WriteLine("[ComImport()]"); | |
148 o.Write("interface " + typeName); | |
149 o.WriteLine(" {"); | |
150 ProcessInterfaceMembersAndInherited(nav, o, parentNav); | |
151 o.WriteLine("}"); | |
152 } | |
153 static void ProcessInterfaceMembersAndInherited(XPathNavigator nav, TextWriter o, XPathNavigator parentNav) { | |
154 XPathItem item = nav.SelectSingleNode("@extends"); | |
155 if (item != null && item.Value[0] != '$') { | |
156 XPathNavigator inav = parentNav.SelectSingleNode("interface[@name='" + item.Value + "']"); | |
157 ProcessInterfaceMembersAndInherited(inav, o, parentNav); | |
158 } | |
159 ProcessInterfaceMembers(nav.SelectChildren(XPathNodeType.Element), o); | |
160 } | |
161 static void ProcessInterfaceMembers(XPathNodeIterator members, TextWriter oattribute) { | |
162 XPathItem item; | |
163 StringWriter omethod = new StringWriter(); | |
164 foreach (XPathNavigator member in members) { | |
165 switch (member.Name) { | |
166 case "desc": | |
167 break; | |
168 case "attribute": { | |
169 String mName = member.SelectSingleNode("@name").Value; | |
170 item = member.SelectSingleNode("@readonly"); | |
171 Boolean mReadOnly = item == null ? false : item.Value == "yes"; | |
172 mName = mName.Substring(0, 1).ToUpper() + mName.Substring(1); | |
173 oattribute.Write("\t"); | |
174 TypeInfo t = GetTypeDeclaration(member); | |
175 oattribute.Write(t.Name); | |
176 oattribute.Write(" "); | |
177 oattribute.Write(mName); | |
178 oattribute.WriteLine(" {"); | |
179 oattribute.Write("\t\t[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] "); | |
180 t.WriteAttributes(oattribute, ParameterType.Return); | |
181 oattribute.WriteLine("get;"); | |
182 if (!mReadOnly) { | |
183 oattribute.Write("\t\t[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] "); | |
184 t.WriteAttributes(oattribute, ParameterType.Param); | |
185 oattribute.WriteLine("set;"); | |
186 } | |
187 oattribute.WriteLine("\t}"); | |
188 } break; | |
189 case "method": { | |
190 String mName = member.SelectSingleNode("@name").Value; | |
191 XPathNodeIterator mParamReturn = member.Select("param[@dir='return']"); | |
192 omethod.WriteLine("\t[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]"); | |
193 omethod.Write("\t"); | |
194 bool mReturn = false; | |
195 if (mParamReturn == null || mParamReturn.Count != 1) { | |
196 omethod.Write("void"); | |
197 } else { | |
198 mParamReturn.MoveNext(); | |
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 | 201 } |
202 mName = mName.Substring(0, 1).ToUpper() + mName.Substring(1); | |
203 omethod.Write(" "); | |
204 omethod.Write(mName); | |
205 omethod.Write("("); | |
206 XPathNodeIterator mParams = member.Select("param"); | |
207 bool first = true; | |
208 if (mParams.MoveNext()) { | |
209 while (true) { | |
210 XPathNavigator mParam = mParams.Current; | |
211 String pDir = mParam.SelectSingleNode("@dir").Value; | |
212 if (pDir == "return" && mReturn) { | |
213 if (mParams.MoveNext()) { | |
214 continue; | |
215 } else { | |
216 break; | |
217 } | |
218 } else if (pDir == "in") { | |
219 } else if (pDir == "out") { | |
220 } else { | |
221 Console.Error.WriteLine("Unsupported parameter direction {0}", pDir); | |
222 } | |
223 if (first) { | |
224 first = false; | |
225 } else { | |
226 omethod.Write(", "); | |
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 | 229 omethod.Write(" p"); |
230 omethod.Write(mParam.SelectSingleNode("@name").Value); | |
231 if (!mParams.MoveNext()) break; | |
232 } | |
233 } | |
234 omethod.WriteLine(");"); | |
235 } break; | |
236 default: | |
237 Console.Error.WriteLine("Unknown member type {0}", member.Name); | |
238 break; | |
239 } | |
240 } | |
241 oattribute.Write((omethod as StringWriter).ToString()); | |
242 } | |
243 private static TypeInfo GetTypeDeclaration(XPathNavigator nav) { | |
244 ParameterType pt = ParameterType.Param; | |
245 return GetTypeDeclaration(nav, ref pt); | |
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 | 251 private static TypeInfo GetTypeDeclaration(XPathNavigator nav, ref ParameterType paramType) { |
252 String mType = nav.SelectSingleNode("@type").Value; | |
253 XPathItem item; | |
254 item = nav.SelectSingleNode("@mod"); | |
255 String mMod = item == null ? null : item.Value; | |
256 item = nav.SelectSingleNode("@safearray"); | |
257 Boolean pArray = item == null ? false : item.Value == "yes"; | |
258 | |
259 TypeInfo t; | |
260 if (!Types.TryGetValue(mType, out t)) { | |
261 Console.Error.WriteLine("Type {0} is not supported", mType); | |
262 t = new TypeInfo("void"); | |
263 } | |
264 if (mMod == "ptr") { | |
265 if (paramType == ParameterType.In) { | |
266 paramType = ParameterType.Reference; | |
267 } else { | |
268 t = new TypeInfo("IntPtr"); | |
269 } | |
270 } else if (mMod == "string") { | |
271 t = new TypeInfo("String", "MarshalAs(UnmanagedType.LPWStr)"); | |
272 } else if (mMod != null) { | |
273 Console.Error.WriteLine("Type modifier {0} is not supported", mMod); | |
274 t = new TypeInfo("void"); | |
275 } | |
276 if (pArray) { | |
277 t = new TypeInfo("Array", "MarshalAs(UnmanagedType.SafeArray)"); | |
278 if (paramType == ParameterType.In || paramType == ParameterType.Out) paramType = ParameterType.Reference; | |
279 } | |
280 return t; | |
281 } | |
282 } |