Você está na página 1de 2

public static void initialize_board(Config cf) { unsafe { int width = cf.Nb_cols; int height = cf.

Nb_rows; b = new Board(&width, &height); } for(int i = 0; i < cf.Nb_cols; ++i) { for(int j = 0; j < cf.Nb_rows; ++j) { unsafe { fixed (Cell* c = &b.grid[i, j]) { c->count = sum_up (&b, i, j); } } } } unsafe class Board { public Cell[,] grid; public Board(int* width, int* height) { grid = new Cell[*width, *height]; } }

The example presents the Board onto the screen using the GTK# libraries. The full code is in Game.cs and the compiler is being called along with `-r:gtk-sharp`. If the assembly is not in the default search path then you need to set `-L path` to point to the path. Remember to set "-unsafe" during compiling but there is no need to say that upon runing the compiled executable.
On Suse Linux, the "gtk-sharp" package exists. But to compile you need to add the option -L /usr/lib/mono/gtk-sharp/

1. To compile the program, type:


mcs -r:gtk-sharp --unsafe Game.cs

2. To run the program, type:


mint Game.exe

When the program would not contain any unsafe keywords, one can remove the --unsafe switch from step 1. At that point the program may also work with the Mono JIT so you can try also `mono Game.exe`. Unsafe code is unlikely to work with the Mono JIT. This paragraph is word from that coursework introduction [UnsafeCSharp] which also contains hint for compiling the program under windows: 1. Download and install the Mono and GTK# installer. 2. Open a command-line prompt and change to the directory containing the program file. 3. . Set the path environment variable so that the Mono command-line tools are available by typing:
set PATH=%PATH%;"C:\Program Files\Mono-1.0.5\bin\"

4. To compile the program, type:


mcs -pkg:gtk-sharp -target:winexe -unsafe Game.cs

5. To run the program, type:


mono Game.exe

When the program code no longer contains any unsafe keywords, you can remove the -unsafe switch from step 4. Importing Native Functions Java has JINI, CSharp has DllImport. I have some experiences with the java native interface support it is has a big problem: there compiled java objects ("*.class") do not have RPATHs or even any other dependency hint. When running a "*.class" or "*.jar" you have to specify all native code dependencies on the command line. The CSharp folks have solved it - using function attributes. Later Java has learned about generic attributes as well. We will see whether it helps with the native code import problems. In C# it does exist from day 1 simply because microsoft has so many native dlls. It was not a good idea to even try to recreated them from square 1 in "pure" managed code. Therefore we can be strict sure that the native function import works. Always. In our later "tomboy"-like gnome panel example it looks like:
// preload /opt/gnome/lib/libpanel-applet-2.so [DllImport("panel-applet-2")] // import this C symbol from the environment static extern void panel_applet_factory_main(IntPtr raw, out int size_hints, int n_elements, int base_size);

That should give you some clues. First of all, it easy to transfer integral types as arguments (and return values) since they identical in C/C++ and C#. For an external struct object just use "IntPtr" to get a generic pointer thing. The "out" parameter hint ensures that the address of object is being transfered. That object is automatically "fixed" of course. - Let's have a look a more problematic thing:
[DllImport("panel-applet-2")] static extern IntPtr panel_applet_new(); [DllImport("panel-applet-2")] static extern unsafe int panel_applet_gconf_get_int(IntPtr raw, string key, out IntPtr opt_error); public unsafe int GconfGetInt(string key) { IntPtr error = IntPtr.Zero; int ret = panel_applet_gconf_get_int(Handle, key, out error); if (error != IntPtr.Zero) throw new GLib.GException (error); return ret; }

Você também pode gostar