What's wrong with this code?

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
 
G

Grant Richins [MS]

Have you checked that waveCaps is not 0, and that ReturnCode is a valid
successful return code?
 
M

Mattias Sjögren

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
 
I

Ignacio Domínguez

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top