Writing C# wrapper for method MP4TagsFetch in LibMP4v2
<p>I will writing a class to reading MP4 files by using of the LibMP4v2 library, but C++ is not my favorite programing language.</p>

<pre><code>The library contains following structure definitions:
 /** Enumeration of possible MP4TagArtwork::type values. */
typedef enum MP4TagArtworkType_e
{
    MP4_ART_UNDEFINED = 0,
    MP4_ART_BMP       = 1,
    MP4_ART_GIF       = 2,
    MP4_ART_JPEG      = 3,
    MP4_ART_PNG       = 4
} MP4TagArtworkType;

/** Data object representing a single piece of artwork. */
typedef struct MP4TagArtwork_s
{
    void*             data; /**&lt; raw picture data */
    uint32_t          size; /**&lt; data size in bytes */
    MP4TagArtworkType type; /**&lt; data type */
} MP4TagArtwork;

typedef struct MP4TagTrack_s
{
    uint16_t index;
    uint16_t total;
} MP4TagTrack;

typedef struct MP4TagDisk_s
{
    uint16_t index;
    uint16_t total;
} MP4TagDisk;

/** Tags &lt;b&gt;convenience&lt;/b&gt; structure.
 *
 *  This structure is used in the tags convenience API which allows for
 *  simplified retrieval and modification of the majority of known tags.
 *
 *  This is a read-only structure and each tag is present if and only if the
 *  pointer is a &lt;b&gt;non-NULL&lt;/b&gt; value. The actual data is backed by a hidden
 *  data cache which is only updated when the appropriate metadata &lt;b&gt;set&lt;/b&gt;
 *  function is used, or if MP4TagsFetch() is invoked. Thus, if other API
 *  is used to manipulate relevent atom structure of the MP4 file, the user
 *  is responsible for re-fetching the data in this structure.
 */
typedef struct MP4Tags_s
{
    void* __handle; /* internal use only */

    const char*        name;
    const char*        artist;
    const char*        albumArtist; 
    const char*        album;
    const char*        grouping;
    const char*        composer;
    const char*        comments;
    const char*        genre;
    const uint16_t*    genreType;
    const char*        releaseDate;
    const MP4TagTrack* track;
    const MP4TagDisk*  disk;
    const uint16_t*    tempo;
    const uint8_t*     compilation;

    const char*     tvShow;
    const char*     tvNetwork;
    const char*     tvEpisodeID;
    const uint32_t* tvSeason;
    const uint32_t* tvEpisode;

    const char* description;
    const char* longDescription;
    const char* lyrics;

    const char* sortName;
    const char* sortArtist;
    const char* sortAlbumArtist;
    const char* sortAlbum;
    const char* sortComposer;
    const char* sortTVShow;

    const MP4TagArtwork* artwork;
    uint32_t             artworkCount;

    const char* copyright;
    const char* encodingTool;
    const char* encodedBy;
    const char* purchaseDate;

    const uint8_t* podcast;
    const char*    keywords;  /* TODO: Needs testing */
    const char*    category;    

    const uint8_t* hdVideo;
    const uint8_t* mediaType;
    const uint8_t* contentRating;
    const uint8_t* gapless;

    const char*     iTunesAccount;
    const uint8_t*  iTunesAccountType;
    const uint32_t* iTunesCountry;
    const uint32_t* contentID;
    const uint32_t* artistID;
    const uint64_t* playlistID;
    const uint32_t* genreID;
    const uint32_t* composerID;
    const char*     xid;
} MP4Tags;
</code></pre>

<p>My C# code is:      </p>

<pre><code>[DllImport("libmp4v2.dll", CharSet = CharSet.Ansi)]
private extern static IntPtr MP4Read([MarshalAs(UnmanagedType.LPStr)] string filePath);

[DllImport("libmp4v2.dll", CharSet = CharSet.Ansi)]
private extern static bool MP4TagsFetch(IntPtr tags, IntPtr fileHandle);

[DllImport("libmp4v2.dll", CharSet = CharSet.Ansi)]
private extern static IntPtr MP4TagsAlloc();

[DllImport("libmp4v2.dll", CharSet = CharSet.Ansi)]
private extern static IntPtr MP4FileInfo([MarshalAs(UnmanagedType.LPStr)] string filePath, uint trackId);

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct MP4TagTrack
{
   public ushort Index;
   public ushort Total;
}

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct MP4TagDisk
        {
            public ushort Index;
            public ushort Total;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct CoverArtBox
        {
            public byte[] data; /**&lt; raw picture data */
            public uint size; /**&lt; data size in bytes */
            public MP4TagArtworkType type; /**&lt; data type */
        }

        public enum MP4TagArtworkType
        {
            MP4_ART_UNDEFINED = 0,
            MP4_ART_BMP = 1,
            MP4_ART_GIF = 2,
            MP4_ART_JPEG = 3,
            MP4_ART_PNG = 4
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct MP4Tags
        {
            public string Name;
            public string Artist;
            public string AlbumArtist;
            public string Album;
            public string Grouping;
            public string Composer;
            public string Comments;
            public string Genre;
            public byte[] GenreType;
            public string ReleaseDate;
            //public MP4TagTrack Track;
            //public MP4TagDisk Disk;
            public uint Tempo;
            public uint Compilation;

            public string TVShow;
            public string TVEpisodeID;
            public string TVNetwork;
            public uint TVSeason;
            public uint TVEpisode;

            public string SortName;
            public string SortArtist;
            public string SortAlbumArtist;
            public string SortAlbum;
            public string SortComposer;
            public string SortTVShow;

            public string Description;
            public string LongDescription;
            public string Lyrics;

            public CoverArtBox[] Artwork;
            public uint ArtworkCount;

            public string Copyright;
            public string EncodingTool;
            public string EncodedBy;
            public string PurchaseDate;

            public uint Podcast;
            public string Keywords;
            public string Category;

            public uint HDVideo;
            public uint MediaType;
            public uint ContentRating;
            public uint Gapless;

            public string iTunesAccount;
            public byte iTunesAccountType;
            public uint iTunesCountry;
            public uint ContentID;
            public uint ArtistID;
            public ulong PlaylistID;
            public uint GenreID;
            public uint ComposerID;
            public string Xid;

            public bool HasMetadata;
        }
</code></pre>

<p>After calling of the external method MP4TagsFetch and converting the IntPtr into my structure are same fields filled with data of other fields:</p>

<pre><code>IntPtr fileHandle = MP4Read(FilePath);

IntPtr tags = MP4TagsAlloc();

if (fileHandle != IntPtr.Zero &amp;&amp; MP4TagsFetch(tags, fileHandle))
    MP4Tags val = (MP4Tags)Marshal.PtrToStructure(tags, typeof(MP4Tags));
</code></pre>

<p>What's going wrong? Can anyone help me?</p>
