4

I am trying to write a wrapper library for MIDI functions in WinMM.dll, but I am having trouble with MIDI long messages. I found this in PIvnoke.net (I added the first line myself):

[StructLayout(LayoutKind.Sequential)]
    public struct MIDIHDR
    {
        IntPtr lpData;
        int dwBufferLength;
        int dwBytesRecorded;
        IntPtr dwUser;
        int dwFlags;
        MIDIHDR lpNext;
        IntPtr reserved;
        int dwOffset;
        IntPtr dwReserved;
    }

But I get an error while compiling:

Error 1 Struct member 'WinMMM.MidiWrapper.MIDIHDR.lpNext' of type 'WinMMM.MidiWrapper.MIDIHDR' causes a cycle in the struct layout C:\Users\Alex\Documents\Visual Studio 2010\Projects\WinMMM\WinMMM\MidiWrapper.cs 219 21 WinMMM

I am using Visual Studio Ultimate 2010, I am making a C# class library, and any help will be appreciated!

Gustavo Mori
  • 8,319
  • 3
  • 38
  • 52
Mika
  • 111
  • 3
  • 10

3 Answers3

4

You can change:

MIDIHDR lpNext;

to:

IntPtr lpNext;

to solve your immediate problem.

The MIDL compiler can't dereference a chain of these structures but if an API call takes one as an argument, with this change the link to the next one will be decoded as a raw pointer, just like first field lpData.

Rick Sladkey
  • 33,988
  • 6
  • 71
  • 95
  • 1
    @Ritch: According to `MMSystem.h` this field is `/* reserved for driver */` so it of no use and `IntPtr` is the best choice to ignore it. – Rick Sladkey May 19 '11 at 00:34
1

I'm not sure the final bit of your correct is right. dwReserved is an array of four DWORD_PTRs (see MIDIHDR on MSDN). You could use something like this:

    // http://msdn.microsoft.com/en-us/library/dd798449%28VS.85%29.aspx
    [StructLayout(LayoutKind.Sequential)]
    public struct MIDIHDR
    {
        public string lpData;
        public int dwBufferLength;
        public int dwBytesRecorded;
        public IntPtr dwUser;
        public int dwFlags;
        public IntPtr lpNext;
        public IntPtr reserved;
        public int dwOffset;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
        public IntPtr[] dwReserved;
    }
Mark Heath
  • 48,273
  • 29
  • 137
  • 194
0

You could also change the declaration of MIDIHDR from a struct to a class type.

Gustavo Mori
  • 8,319
  • 3
  • 38
  • 52