What's wrong with this code?

  • Thread starter Thread starter Ignacio Domínguez
  • Start date Start date
I

Ignacio Domínguez

Hi. I'm writing an application and I'm getting a weird error in this code:

DeviceID = 0;
wOutCaps = new WaveOutCaps();
IntPtr waveCaps = Marshal.AllocHGlobal(Marshal.SizeOf(wOutCaps));
Marshal.StructureToPtr(wOutCaps, waveCaps, true);
ReturnCode = waveOutGetDevCaps((uint)DeviceID, out waveCaps,
(uint)Marshal.SizeOf(wOutCaps));
wOutCaps = (WaveOutCaps)Marshal.PtrToStructure(waveCaps,
typeof(WaveOutCaps) ); // I GET HERE AN ERROR (OBJECT NOT SET TO INSTANCE OF
AN OBJECT)
Marshal.FreeHGlobal(waveCaps);

WaveOutCaps is a structure defined as follows:

[StructLayout(LayoutKind.Sequential)]
public struct WaveOutCaps
{
public ushort wManufacturerID;
public ushort wProductID;
public uint vDriverVersion;
public string szProductName;
public WaveFormats dwFormats;
public ushort wChannels;
public ushort wReserved1;
public uint dwSupport;
}

I wonder why is this error showing up... Any ideas?

Thanks

Ignacio Domínguez
 
Have you checked that waveCaps is not 0, and that ReturnCode is a valid
successful return code?
 
Ignacio,
[StructLayout(LayoutKind.Sequential)]
public struct WaveOutCaps
{
public ushort wManufacturerID;
public ushort wProductID;
public uint vDriverVersion;
public string szProductName;
public WaveFormats dwFormats;
public ushort wChannels;
public ushort wReserved1;
public uint dwSupport;
}

I wonder why is this error showing up... Any ideas?

First of all your struct declaration is incorrect. Try it like this
instead

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
public struct WaveOutCaps
{
public ushort wManufacturerID;
public ushort wProductID;
public uint vDriverVersion;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=32)]
public string szProductName;
public WaveFormats dwFormats;
public ushort wChannels;
public ushort wReserved1;
public uint dwSupport;
}

Second, you seem to be doing a lot more work than you have to with the
Marshal class. If you declare the function correctly you shouldn't
have to do that, just pass in the struct variable you want to be
filled.

[DllImport("winmm.dll", CharSet=CharSet.Auto)]
static extern uint waveOutGetDevCaps(IntPtr uDeviceID, out WAVEOUTCAPS
pwoc, uint cbwoc);



Mattias
 
thanks you so much. this worked perfectly. I've been having a lot of trouble
using API since I've never done any serious C (C++) coding. Perhaps you can
give me some advice on doing this type of declarations/conversions, maybe
also pointing to a place to translate C types into .NET. Thank you again.


Mattias Sjögren said:
Ignacio,
[StructLayout(LayoutKind.Sequential)]
public struct WaveOutCaps
{
public ushort wManufacturerID;
public ushort wProductID;
public uint vDriverVersion;
public string szProductName;
public WaveFormats dwFormats;
public ushort wChannels;
public ushort wReserved1;
public uint dwSupport;
}

I wonder why is this error showing up... Any ideas?

First of all your struct declaration is incorrect. Try it like this
instead

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
public struct WaveOutCaps
{
public ushort wManufacturerID;
public ushort wProductID;
public uint vDriverVersion;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=32)]
public string szProductName;
public WaveFormats dwFormats;
public ushort wChannels;
public ushort wReserved1;
public uint dwSupport;
}

Second, you seem to be doing a lot more work than you have to with the
Marshal class. If you declare the function correctly you shouldn't
have to do that, just pass in the struct variable you want to be
filled.

[DllImport("winmm.dll", CharSet=CharSet.Auto)]
static extern uint waveOutGetDevCaps(IntPtr uDeviceID, out WAVEOUTCAPS
pwoc, uint cbwoc);



Mattias
 
Back
Top