2 * Copyright (C) 2009-2010 Red Hat Inc.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 (* Please read generator/README first. *)
26 open Generator_docstrings
27 open Generator_optgroups
28 open Generator_actions
29 open Generator_structs
31 let rec generate_csharp () =
32 generate_header CPlusPlusStyle LGPLv2plus;
34 (* XXX Make this configurable by the C# assembly users. *)
35 let library = "libguestfs.so.0" in
38 // These C# bindings are highly experimental at present.
40 // Firstly they only work on Linux (ie. Mono). In order to get them
41 // to work on Windows (ie. .Net) you would need to port the library
42 // itself to Windows first.
44 // The second issue is that some calls are known to be incorrect and
45 // can cause Mono to segfault. Particularly: calls which pass or
46 // return string[], or return any structure value. This is because
47 // we haven't worked out the correct way to do this from C#.
49 // The third issue is that when compiling you get a lot of warnings.
50 // We are not sure whether the warnings are important or not.
52 // Fourthly we do not routinely build or test these bindings as part
53 // of the make && make check cycle, which means that regressions might
56 // Suggestions and patches are welcome.
61 // mono Libguestfs.exe
63 // (You'll probably want to add a Test class / static main function
64 // otherwise this won't do anything useful).
68 using System.Runtime.InteropServices;
69 using System.Runtime.Serialization;
70 using System.Collections;
74 class Error : System.ApplicationException
76 public Error (string message) : base (message) {}
77 protected Error (SerializationInfo info, StreamingContext context) {}
85 static extern IntPtr guestfs_create ();
89 _handle = guestfs_create ();
90 if (_handle == IntPtr.Zero)
91 throw new Error (\"could not create guestfs handle\");
95 static extern void guestfs_close (IntPtr h);
99 guestfs_close (_handle);
103 static extern string guestfs_last_error (IntPtr h);
105 " library library library;
107 (* Generate C# structure bindings. We prefix struct names with
108 * underscore because C# cannot have conflicting struct names and
109 * method names (eg. "class stat" and "stat").
113 pr " [StructLayout (LayoutKind.Sequential)]\n";
114 pr " public class _%s {\n" typ;
117 | name, FChar -> pr " char %s;\n" name
118 | name, FString -> pr " string %s;\n" name
120 pr " uint %s_len;\n" name;
121 pr " string %s;\n" name
123 pr " [MarshalAs (UnmanagedType.ByValTStr, SizeConst=16)]\n";
124 pr " string %s;\n" name
125 | name, FUInt32 -> pr " uint %s;\n" name
126 | name, FInt32 -> pr " int %s;\n" name
127 | name, (FUInt64|FBytes) -> pr " ulong %s;\n" name
128 | name, FInt64 -> pr " long %s;\n" name
129 | name, FOptPercent -> pr " float %s; /* [0..100] or -1 */\n" name
135 (* Generate C# function bindings. *)
137 fun (name, style, _, _, _, shortdesc, _) ->
138 let rec csharp_return_type () =
147 | RBufferOut n -> "string"
148 | RStruct (_,n) -> "_" ^ n
149 | RHashtable n -> "Hashtable"
150 | RStringList n -> "string[]"
151 | RStructList (_,n) -> sprintf "_%s[]" n
153 and c_return_type () =
162 | RBufferOut _ -> "string"
163 | RStruct (_,n) -> "_" ^ n
165 | RStringList _ -> "string[]"
166 | RStructList (_,n) -> sprintf "_%s[]" n
168 and c_error_comparison () =
173 | RInt64 _ -> "== -1"
181 | RStructList (_,_) -> "== null"
183 and generate_extern_prototype () =
184 pr " static extern %s guestfs_%s (IntPtr h"
185 (c_return_type ()) name;
188 | Pathname n | Device n | Dev_or_Path n | String n | OptString n
189 | FileIn n | FileOut n
192 pr ", [In] string %s" n
193 | StringList n | DeviceList n ->
194 pr ", [In] string[] %s" n
204 and generate_public_prototype () =
205 pr " public %s %s (" (csharp_return_type ()) name;
206 let comma = ref false in
208 if !comma then pr ", ";
213 | Pathname n | Device n | Dev_or_Path n | String n | OptString n
214 | FileIn n | FileOut n
217 next (); pr "string %s" n
218 | StringList n | DeviceList n ->
219 next (); pr "string[] %s" n
221 next (); pr "bool %s" n
223 next (); pr "int %s" n
225 next (); pr "long %s" n
229 and generate_call () =
230 pr "guestfs_%s (_handle" name;
231 List.iter (fun arg -> pr ", %s" (name_of_argt arg)) (snd style);
235 pr " [DllImport (\"%s\")]\n" library;
236 generate_extern_prototype ();
238 pr " /// <summary>\n";
239 pr " /// %s\n" shortdesc;
240 pr " /// </summary>\n";
241 generate_public_prototype ();
243 pr " %s r;\n" (c_return_type ());
246 pr " if (r %s)\n" (c_error_comparison ());
247 pr " throw new Error (guestfs_last_error (_handle));\n";
248 (match fst style with
251 pr " return r != 0 ? true : false;\n"
253 pr " Hashtable rr = new Hashtable ();\n";
254 pr " for (size_t i = 0; i < r.Length; i += 2)\n";
255 pr " rr.Add (r[i], r[i+1]);\n";
257 | RInt _ | RInt64 _ | RConstString _ | RConstOptString _
258 | RString _ | RBufferOut _ | RStruct _ | RStringList _
264 ) all_functions_sorted;