HackWeek 3. Day 1.
I’m in Provo, UT to spend all week in HackWeek. My idea is based on the effort done by Manuel and me some months ago, the idea is simple, but needed, port everything to MoonLight. We’ll see what happens.
I’m in Provo, UT to spend all week in HackWeek. My idea is based on the effort done by Manuel and me some months ago, the idea is simple, but needed, port everything to MoonLight. We’ll see what happens.
Wondering how to develop maemo# applications? Follow this recipe to do so:
And here it is, running in the scratchbox:
If you are trying to get Mono.Cecil.TypeDefinition from a Mono.Cecil.TypeReference (like I was) you can start by trying the following code, just an idea:
DefaultAssemblyResolver resolver = new DefaultAssemblyResolver ();
AssemblyNameReference assem = new AssemblyNameReference ();
assem.Name = "mscorlib";
assem.Version = new Version (2, 0); //Try 1.0 also
AssemblyDefinition assemDef = resolver.Resolve (assem);
foreach (TypeReference typeReference in _library.MainModule.TypeReferences) {
TypeDefinition definition = assemDef.MainModule.Types [typeReference.FullName];
Console.WriteLine (definition.FullName);
}
Don’t forget to add using Mono.Cecil. Above code solve my problems to get those DataType-like structures, such as System.Int32, System.Int16 and so on, which aren’t loaded when you are doing reverse engineering.
I commented this days ago, now here comes the explanation.
The idea is the following, you have to send through sockets a marshalled structure, this structure will be received by socket server written in C. Then, for example I have:
#pragma pack (1)
struct sample {
int index;
int length; /* Indicates value length */
char *value; /* This value might be any value */
};
typedef struct sample sample_t;
#pragma end
That C structure, in C# is, after marshalling:
[StructLayout (LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
public struct Sample
{
public int Index;
public int DataLength;
[MarshalAs (UnmanagedType.ByValArray, ArraySubType = UnmanagedType.I1, SizeConst = 1)]
public byte []Data;
}
We have our marshalled C# structure. Did you notice the SizeConst value? Well that SizeConst, will, when using Marshal.SizeOf (typeof (Sample)), return a structure known-bytes size. If you are planning to use real-sized structure you MUST marshall them, and there comes the pain. Why? Because you actually need to know about bytes and size of each element send or received by differents processes, in this example, through IP sockets.
C structure uses a dynamic array and I want to use it that way. By setting the size to 1 in C# structure forces me to use 1 byte instead. Really problematic isn’t it? Until today I haven’t yet found the way to do it automatically. My solution is to use Array.Copy to copy the marshalled value (value contained in the byte[]) after the full structure was marshalled, it works, but isn’t too fancy, and when using a Structure that contains a byte[] and setting into that byte[] another Structure that also contains byte[] the problems increase because you need to Array.Copy each one of them.
By the way, I’m using the “google solution” to marshall .NET structures to byte[], am not sure who is the original author of the following code, but seems to be solution to convert from any marshalled structure to bytes array, and viceversa:
public static object RawDeserialize (byte[] rawdatas, Type anytype) {
int rawsize = Marshal.SizeOf (anytype);
if (rawsize > rawdatas.Length)
return null;
GCHandle handle = GCHandle.Alloc (rawdatas, GCHandleType.Pinned);
IntPtr buffer = handle.AddrOfPinnedObject ();
object retobj = Marshal.PtrToStructure (buffer, anytype);
handle.Free ();
return retobj;
}
public static byte[] RawSerialize (object anything)
{
int rawsize = Marshal.SizeOf (anything);
byte[] rawdatas = new byte [rawsize];
GCHandle handle = GCHandle.Alloc (rawdatas, GCHandleType.Pinned);
IntPtr buffer = handle.AddrOfPinnedObject ();
Marshal.StructureToPtr (anything, buffer, false);
handle.Free ();
return rawdatas;
}
Be aware that are some tips&tricks while marshalling and you must follow each one of them. Because we are living in managed world and unmanaged is almost a sin.
Since past week, I’m writing a socket server to enable IPC between .NET-based clients and Linux acquisition servers. TCP/IP multi-threaded server isn’t the problem, but clients are, why? Because of .NET’s marshaling. What’s my idea? this idea is the basic “header-data message”, you know, use the header to set details related to data, so I will have header { server-code, data-length, timestamp, etc, data }, and data will change depending on the server. Implementing that in C/C++ or any other not-managed programming language is easy, neither unmanaged nor managed C# code are working, I have already solved the problem, but it’s hack-like, and I want a prettier, better and nicer solution.
I’ll try to post samples as sooner as possible to show this problem, maybe testing same code with gmcs may work, I’ll figure it out tomorrow.
I usually use both mono-svn-version and mono-release versions to test new features and live in the edge. Compiling every module takes time, so I decided to write a bash script to do that, the automated-way.
I will add it tomorrow afternoon to MonoHispano‘s SVN, or until Novell‘s server bring back to life, in the meanwhile the source is uploaded. If there is any problem with the script, please let me know.
I’m starting the Mono POSIX shared memory wrapping, decided to begin dllimporting shm_open, however doesn’t seems to be easy at all, my current effort is:
using System;
using System.Runtime.InteropServices;
namespace Mono.Posix {
public class SharedMemory
{
public SharedMemory ()
{ }
[DllImport ("librt", EntryPoint="shm_open", CharSet=CharSet.Ansi,
CallingConvention=CallingConvention.StdCall)]
public static extern IntPtr Open (
[MarshalAs (UnmanagedType.LPStr)] string name,
int oflag,
int mode_t);
public static void Main (string []args)
{
//O_RDONLY = 00
//O_WRONLY = 01
//O_RDWR = 02
SharedMemory m = new SharedMemory ();
SharedMemory.Open ("test", 0, 777);
}
}
}
After compiling and running, I get:
SharedMemory.cs(22,17): warning CS0219: The variable `m' is assigned but its value is never used
Compilation succeeded - 1 warning(s)
Unhandled Exception: System.ExecutionEngineException: SIGILL
at [0x00000] unknown method
at (wrapper managed-to-native) Mono.Posix.SharedMemory:Open (string,int,int)
at Mono.Posix.SharedMemory.Main (System.String[] args) [0x00000]
Ignore the warning and notice the SIGILL related exception, may it be something about current marshaling? Will again, but later, I need to rest, tomorrow will wake up earlier.
I don’t usually send emails to mailing lists that am subscribed to and wait for an answer, when I do is because I couldn’t find any solution to my problem or, in the other way, want to announce something (like our Mono Hispano ezine!). However I (think that) finally find the answer (’cause still needs further testing) for bringing-to-front widgets drawn in a Gtk.Layout, using the following code as primary sample:
using Gtk;
using System;
public class Sample
{
public static void Main ()
{
Application.Init ();
Window window = new Window ("");
Layout layout = new Layout (new Adjustment (IntPtr.Zero),
new Adjustment (IntPtr.Zero));
Button b1 = new Button ("1");
Button b2 = new Button ("2");
layout.Put (b1, 10, 20);
layout.Put (b2, 15, 15);
ScrolledWindow scrolled = new ScrolledWindow ();
scrolled.AddWithViewport (layout);
window.Add (scrolled);
window.ShowAll ();
Application.Run ();
}
}
You will notice the overlap of b2 over b1, if you switch lines b1 overlaps b2, however, there isn’t a solution for doing this after showing the Gtk.Window.
Solution? Use Gtk.EventBox, after reading gmane’s archive I figured it out! However I didn’t know Gtk.Button doesn’t owns a Gdk.Window, by don’t owning a Gdk.Window, Gtk.Button draws over anything (or any other Gdk.Windowless-widget) so, that might the problem am facing recently. Using Gdk.Window.Lower (), sends to back, Next code shows solution:
using Gtk;
using System;
public class Sample
{
public static void Main ()
{
Application.Init ();
EventBox e1 = new EventBox ();
EventBox e2 = new EventBox ();
Window window = new Window ("");
Layout layout = new Layout (new Adjustment (IntPtr.Zero),
new Adjustment (IntPtr.Zero));
layout.Add (e1);
layout.Add (e2);
Button b1 = new Button ("1");
b1.Clicked += new EventHandler (ButtonClick);
e1.Add (b1);
Button b2 = new Button ("2");
b2.Clicked += new EventHandler (ButtonClick);
e2.Add (b2);
layout.Move (e1, 10, 20);
layout.Move (e2, 15, 15);
ScrolledWindow scrolled = new ScrolledWindow ();
scrolled.AddWithViewport (layout);
window.Add (scrolled);
window.ShowAll ();
Application.Run ();
}
public static void ButtonClick (object o, EventArgs a)
{
Button b = o as Button;
b.GdkWindow.Raise ();
}
}
Nice!. By the way, Rodolfo and I improved MonoUML a little bit, now MonoUML gots its history navigator
