System.NullReferenceException on API call

  • Thread starter R. van der Welle
  • Start date
R

R. van der Welle

Hi All,

I am upgrading my app (working well with VB6) to VB.NET. It sends MIDI
messages using the API multimedia winmm.dll .
These functions are declared:

Public Declare Function timeSetEvent Lib "winmm.dll" (ByVal uDelay As
Integer, _
ByVal uResolution As Integer, ByVal lpFunction As MidiPlayDelegate, _
ByVal dwUser As Integer, ByVal uFlags As Integer) As Integer

Delegate Function MidiPlayDelegate(ByVal lTimerID As Integer, ByVal dwMsg As
Integer, _
ByVal dwUser As Integer, ByVal lParam1 As Integer, ByVal lParam2 As
Integer) As Integer

and a function MidiPlay is available:
Public Function MidiPlay(ByVal lTimerID As Integer, ByVal dwMsg As Integer,
_
ByVal dwUser As Integer, ByVal lParam1 As Integer, ByVal lParam2 As
Integer) As Integer
...
lRet = midiOutShortMsg(hMidiOut, mididata)
...
End Function
----------------------------------------------------------------------------
-----

A MIDI port is opened by a call to midiOutOpen, then a timer is started by
the statement
lTimerID = timeSetEvent(1, 1, AddressOf MidiPlay, 0, 1)
which runs in its own thread.
On each time event the call back function MidiPlay is called, which in turn
sends the MIDI data through
lRet = midiOutShortMsg(hMidiOut, mididata)

When the program is run a System.NullReferenceException occurs in an Unknown
Module (the
MidiPlayDelegate, I guess), because
"Object reference not set to an instance of an object"

Which object reference should be set?

Thank you for your help,

ReinierVDW
 
S

Stephen Martin

Your problem is probably on this line:

lTimerID = timeSetEvent(1, 1, AddressOf MidiPlay, 0, 1)

The delegate created by the AddressOf MidiPlay statement does not have any
references to it so it will be garbage collected. If you need a delegate
that will stick around for future callbacks you must keep a live reference
to it. For example:

in your class create a class level delegate variable
Private m_TimerCallback as MDIPlayDelegate

then in the code that sets up the timer callbacks:

m_TimerCallback = New MDIPlayDelegate(AddressOf MDIPlay)
lTimerID = timeSetEvent(1, 1, m_TimerCallback, 0, 1)

now the delegate will stick around as long as your class does.
 
H

Herfried K. Wagner [MVP]

* "R. van der Welle said:
A MIDI port is opened by a call to midiOutOpen, then a timer is started by
the statement
lTimerID = timeSetEvent(1, 1, AddressOf MidiPlay, 0, 1)
which runs in its own thread.
On each time event the call back function MidiPlay is called, which in turn
sends the MIDI data through
lRet = midiOutShortMsg(hMidiOut, mididata)

When the program is run a System.NullReferenceException occurs in an Unknown
Module (the
MidiPlayDelegate, I guess), because
"Object reference not set to an instance of an object"

Which object reference should be set?

Don't forget to save a reference to the delegate!

Simple sample written by Armin Zingler:

\\\
dim o as CallBack

o = new CallBack(addressof CallBackSub)
'...

private sub CallBackSub
end sub
///
 

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