[Mono-dev] Marshalling a struct inside a struct

Justin Cherniak compwiz312 at gmail.com
Tue Dec 16 21:26:41 EST 2008


Sorry, I didn't complete the message.  You would then do:

[DllImport("libgpod.dll")]
static extern Itdb_iTunesDB* itdb_parse(string mp, IntPtr ge);

Itdb_iTunesDB* database = itdb_parse("G:", IntPtr.Zero);

then use pointer dereference operators on the pointer such as:

uint version = database->version;

etc...


On Tue, Dec 16, 2008 at 8:25 PM, Justin Cherniak <compwiz312 at gmail.com>wrote:

> Dudemullet,
>
> 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;
> }
>
> [DllImport("libgpod.dll")]
> 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 (
> http://code.google.com/p/ffmpeg-sharp).
>
> Thanks,
> Justin Cherniak
>
> P.S. Did you know there is a managed ipod library, ipod-sharp (
> http://download.banshee-project.org/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/6610a00c/attachment.html 


More information about the Mono-devel-list mailing list