Click here to Skip to main content
15,885,216 members
Please Sign up or sign in to vote.
5.00/5 (2 votes)
See more:
I'm using some midi API functions that take a MIDIHDR structure.
C#
[StructLayout(LayoutKind.Sequential)]
public struct MIDIHDR
{
    public IntPtr lpData;
    public int dwBufferLength;
    public int dwBytesRecorded;
    public IntPtr dwUser;
    public int dwFlags;
    public IntPtr lpNext;
    public IntPtr reserved;
    public int dwOffset;
    public IntPtr dwReserved;
}
lpData is a pointer to the data. This data is an array of MIDIEVENT structures
[StructLayout(LayoutKind.Sequential)]
public struct MIDIEVENT
{
    public uint dwDeltaTime;
    public uint dwStreamID;
    public uint dwEvent;
}
If I only have one element in the array I can use
int eventSize = Marshal.SizeOf(ev) * events.Length;
IntPtr eventPointer = Marshal.AllocHGlobal(eventSize);
for (int i = 0; i < events.Length; i++)
    Marshal.StructureToPtr(events[i], (IntPtr)((int)eventPointer + (eventSize * i)), false);
but I get Arithmetic operation resulted in an overflow when the second event is reached when playing the events (midiStreamRestart(handle)) if there is more than one element.

So, what's the best way to marshal an array of structures, and why doesn't the above work?
Posted
Updated 25-Aug-09 11:19am
v2

1 solution

Hi Dave,

I have avoided such complexities till now, except for once, a rather simple variable array length.

Here are the results of the Antwerp jury:
In
[1]  int eventSize = Marshal.SizeOf(ev) * events.Length;
[2]  IntPtr eventPointer = Marshal.AllocHGlobal(eventSize);
[3]  for (int i = 0; i < events.Length; i++)
[4]      Marshal.StructureToPtr(events[i], (IntPtr)((int)eventPointer + (eventSize * i)), false);

There is something fishy about eventSize;
[1] is an attempt to compute the overall size; it may be correct, I am not sure, as Sizeof(ev) is the size of one struct and could be rounded up to a multiple of 16 or so, whereas an array would not contain padding bytes between elements.
And [4] treats eventSize as if it were the size of a single element, which it isn't. So that is probably the direct cause of your overflow.
Seems like you want to move the multiplication from [1] to [2].

FWIW: IntPtr will adapt to Win32/Win64 as you probably know; don't let it fool you.

:)
 
Share this answer
 
v2
Comments
DaveyM69 15-Apr-12 8:08am    
Edited to remove br tags in pre blocks as they are being displayed as plain text

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900