Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C#
I'm using some midi API functions that take a MIDIHDR structure.
[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 14-Aug-09 11:29am
DaveyM6976.1K
Edited 25-Aug-09 11:19am
0x3c033.2K
v2

1 solution

Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

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.

Smile | :)
  Permalink  
v2
Comments
DaveyM69 at 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)

  Print Answers RSS
0 OriginalGriff 220
1 ProgramFOX 120
2 Richard MacCutchan 100
3 kbrandwijk 90
4 ChauhanAjay 80
0 Sergey Alexandrovich Kryukov 9,050
1 OriginalGriff 8,151
2 CPallini 2,613
3 Richard MacCutchan 2,221
4 Abhinav S 1,928


Advertise | Privacy | Mobile
Web04 | 2.8.140827.1 | Last Updated 15 Apr 2012
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100