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#. Also
48 // we don't handle functions that take optional arguments at all.
50 // The third issue is that when compiling you get a lot of warnings.
51 // We are not sure whether the warnings are important or not.
53 // Fourthly we do not routinely build or test these bindings as part
54 // of the make && make check cycle, which means that regressions might
57 // Suggestions and patches are welcome.
62 // mono Libguestfs.exe
64 // (You'll probably want to add a Test class / static main function
65 // otherwise this won't do anything useful).
69 using System.Runtime.InteropServices;
70 using System.Runtime.Serialization;
71 using System.Collections;
75 class Error : System.ApplicationException
77 public Error (string message) : base (message) {}
78 protected Error (SerializationInfo info, StreamingContext context) {}
86 static extern IntPtr guestfs_create ();
90 _handle = guestfs_create ();
91 if (_handle == IntPtr.Zero)
92 throw new Error (\"could not create guestfs handle\");
96 static extern void guestfs_close (IntPtr h);
100 guestfs_close (_handle);
104 static extern string guestfs_last_error (IntPtr h);
106 " library library library;
108 (* Generate C# structure bindings. We prefix struct names with
109 * underscore because C# cannot have conflicting struct names and
110 * method names (eg. "class stat" and "stat").
114 pr " [StructLayout (LayoutKind.Sequential)]\n";
115 pr " public class _%s {\n" typ;
118 | name, FChar -> pr " char %s;\n" name
119 | name, FString -> pr " string %s;\n" name
121 pr " uint %s_len;\n" name;
122 pr " string %s;\n" name
124 pr " [MarshalAs (UnmanagedType.ByValTStr, SizeConst=16)]\n";
125 pr " string %s;\n" name
126 | name, FUInt32 -> pr " uint %s;\n" name
127 | name, FInt32 -> pr " int %s;\n" name
128 | name, (FUInt64|FBytes) -> pr " ulong %s;\n" name
129 | name, FInt64 -> pr " long %s;\n" name
130 | name, FOptPercent -> pr " float %s; /* [0..100] or -1 */\n" name
136 (* Generate C# function bindings. *)
138 fun (name, (ret, args, optargs), _, _, _, shortdesc, _) ->
139 let rec csharp_return_type () =
148 | RBufferOut n -> "string"
149 | RStruct (_,n) -> "_" ^ n
150 | RHashtable n -> "Hashtable"
151 | RStringList n -> "string[]"
152 | RStructList (_,n) -> sprintf "_%s[]" n
154 and c_return_type () =
163 | RBufferOut _ -> "string"
164 | RStruct (_,n) -> "_" ^ n
166 | RStringList _ -> "string[]"
167 | RStructList (_,n) -> sprintf "_%s[]" n
169 and c_error_comparison () =
174 | RInt64 _ -> "== -1"
182 | RStructList (_,_) -> "== null"
184 and generate_extern_prototype () =
185 pr " static extern %s guestfs_%s (IntPtr h"
186 (c_return_type ()) name;
189 | Pathname n | Device n | Dev_or_Path n | String n | OptString n
190 | FileIn n | FileOut n
193 pr ", [In] string %s" n
194 | StringList n | DeviceList n ->
195 pr ", [In] string[] %s" n
200 | Int64 n | Pointer (_, n) ->
205 and generate_public_prototype () =
206 pr " public %s %s (" (csharp_return_type ()) name;
207 let comma = ref false in
209 if !comma then pr ", ";
214 | Pathname n | Device n | Dev_or_Path n | String n | OptString n
215 | FileIn n | FileOut n
218 next (); pr "string %s" n
219 | StringList n | DeviceList n ->
220 next (); pr "string[] %s" n
222 next (); pr "bool %s" n
224 next (); pr "int %s" n
225 | Int64 n | Pointer (_, n) ->
226 next (); pr "long %s" n
230 and generate_call () =
231 pr "guestfs_%s (_handle" name;
232 List.iter (fun arg -> pr ", %s" (name_of_argt arg)) args;
236 pr " [DllImport (\"%s\")]\n" library;
237 generate_extern_prototype ();
239 pr " /// <summary>\n";
240 pr " /// %s\n" shortdesc;
241 pr " /// </summary>\n";
242 generate_public_prototype ();
244 pr " %s r;\n" (c_return_type ());
247 pr " if (r %s)\n" (c_error_comparison ());
248 pr " throw new Error (guestfs_last_error (_handle));\n";
252 pr " return r != 0 ? true : false;\n"
254 pr " Hashtable rr = new Hashtable ();\n";
255 pr " for (size_t i = 0; i < r.Length; i += 2)\n";
256 pr " rr.Add (r[i], r[i+1]);\n";
258 | RInt _ | RInt64 _ | RConstString _ | RConstOptString _
259 | RString _ | RBufferOut _ | RStruct _ | RStringList _
265 ) all_functions_sorted;