[Mono-dev] Marshalling a struct inside a struct

Justin Cherniak compwiz312 at gmail.com
Tue Dec 16 21:25:07 EST 2008


You basically have 2 choices, the managed and the unmanaged way.

If you want to keep everything safe, you can replace all the pointers inside
the struct with IntPtrs so you would have:
public class Itdb_iTunesDB {
   IntPtr tracks;
   IntPtr playlists;
   string filename;
   IntPtr  device;
   uint version;
   ulong id;

   ulong usertype;
   IntPtr userdata;

   Delegate<> userdata_duplicate;
   Delegate<> userdata_destroy;

static extern IntPtr itdb_parse(string mp, IntPtr ge);

IntPtr pDatabase = itdb_parse("G:", IntPtr.Zero);
itdb database = (Itdb)Marshal.PtrToStructure(pDatabase);

And then for the inner pointers, use the same Marshal.PtrToStructure(), but
as you can imagine this gets pretty clunky.  The other option is to use
completly unmanaged definitions for your structs (eg. no strings).  This
allows you to marshal them directly as pointers.

eg. Define your managed struct as such:
struct Itdb_iTunesDB {
   GList* tracks; // Define GList somewhere or just cast it to Track*, I
don't know how it is defined.
   GList* playlists;
   sbyte* pfilename;
   string filename {
       get {return new string(pfilename); }
   Itdb_Device* device;
   uint version;
   ulong id;

   ulong usertype;
   void* userdata;

   void* puserdata_duplicate;
   ItdbUserDataDuplicateFunc userdata_duplicate { // Define delegates
somewhere else
        get { return Marshal.DelegateForFunctionPtr(puserdata_duplicate); }

   void* puserdata_destroy;
   ItdbUserDataDestroyFunc userdata_duplicate {
        get { return Marshal.DelegateForFunctionPtr(puserdata_destroy); }

Obviously defining your structs this way involves a bit of work but in the
end they become much easier to use as long as you are comfortable with using
unmanaged code.  If you want to see an example of how this is put together,
check out my bindings for ffmpeg, ffmpeg-sharp (

Justin Cherniak

P.S. Did you know there is a managed ipod library, ipod-sharp (

On Thu, Dec 11, 2008 at 10:33 PM, Dudemullet <elpaip at gmail.com> wrote:

> hello,
> I have a struct that looks like this
>  ++ Unmanaged struct ++
> typedef struct {
>    GList *tracks;
>    GList *playlists;
>    gchar *filename;
>    Itdb_Device *device;
>    guint32 version;
>    guint64 id;
>    guint64 usertype;
>    gpointer userdata;
>    ItdbUserDataDuplicateFunc userdata_duplicate;
>    ItdbUserDataDestroyFunc userdata_destroy;
> } Itdb_iTunesDB;
> ++++++++++++++++++++
> and I have a function inside a dll that is gonna populate it and Ive tried
> various ways to declare  the return type either by IntPtr and later using
> Marshal.PtrtoStructure but when I try and use this function I get the error
> "The structure must not be a value class".
> this is how I tried to implement my function
>  ++ function ++
>  [DllImport("libgpod.dll")]
>   static extern itdb itdb_parse(string mp, IntPtr ge);
>  itdb database = itdb_parse("G:", IntPtr.Zero);
> ++++++++++++++++++++++++++++++++
> In the source I can see that "itdb_parse" returns a Itdb_iTunesDB pointer
> so
> maybe I could use classes but what about the Itdb_Device struct that inside
> this struct ? Also if I need to implement the class, what should I do  Any
> suggestions ?
> Thank you
> --
> View this message in context:
> http://www.nabble.com/Marshalling-a-struct-inside-a-struct-tp20969792p20969792.html
> Sent from the Mono - Dev mailing list archive at Nabble.com.
> _______________________________________________
> Mono-devel-list mailing list
> Mono-devel-list at lists.ximian.com
> http://lists.ximian.com/mailman/listinfo/mono-devel-list
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.ximian.com/pipermail/mono-devel-list/attachments/20081216/3903d881/attachment-0001.html 

More information about the Mono-devel-list mailing list