tags:

views:

836

answers:

2

Callbacks in VB (from C dll).

I need to pass a vb function as a callback to a c function in a dll. I know I need to use addressof for the function but I'm getting more and more confused as to how to do it.

Details:

The function in the dll that I'm passing the address of a callback to is defined in C as :

PaError Pa_OpenStream( PaStream** stream,
                       const PaStreamParameters *inputParameters,
                       const PaStreamParameters *outputParameters,
                       double sampleRate,
                       unsigned long framesPerBuffer,
                       PaStreamFlags streamFlags,
                       PaStreamCallback *streamCallback,
                       void *userData );

where the function is parameter 7, *streamCallback. The type PaStreamCallback is defines thusly:

typedef int PaStreamCallback(
    const void *input, void *output,
    unsigned long frameCount,
    const PaStreamCallbackTimeInfo* timeInfo,
    PaStreamCallbackFlags statusFlags,
    void *userData );

In my vb project I have:

Private Declare Function Pa_OpenStream Lib "portaudio_x86.dll" _
        (     ByVal stream As IntPtr _
            , ByVal inputParameters As IntPtr _
            , ByVal outputParameters As PaStreamParameters _
            , ByVal samprate As Double _
            , ByVal fpb As Double _
            , ByVal paClipoff As Long _
            , ByVal patestCallBack As IntPtr _
            , ByVal data As IntPtr) As Integer

(don't worry if I've mistyped some of the other parameters, I'll get to them later! Let's concentrate on the callback for now.)

In module1.vb I have defined the callback function:

Function MyCallback( ByVal inp As Byte, _ ByVal outp As Byte, _ ByVal framecount As Long, _ ByVal pastreamcallbacktimeinfo As Byte, _ ByVal pastreamcallbackflags As Byte, _ ByVal userdata As Byte) As Integer ' do clever things here End Function

The external function in the dll is called with

err = Pa_OpenStream(    ptr, _
      nulthing, _
      outputParameters, _
      SAMPLE_RATE, _
      FRAMES_PER_BUFFER, _
      clipoff, _
      AddressOf MyCallback, _
      dataptr)

This is broken in the declaration of the external function - it doesn't like the type IntPtr as a function pointer for AddressOf.

Can anyone show me how to implement passing this callback function please ?

Many thanks David

A: 

This MSDN article will help: How To Callback Visual Basic Functions From a C DLL

Eduard Wirch
The linked page is for Visual Basic 5, which is decidedly old. It looks like Davey is using Visual Basic .NET, which will require a different strategy than ancient VB5.
John Ledbetter
A: 

I've read it, but I'm struggling to see what I'm doing wrong. Their example has ExecuteCallback (ByVal pFunc as long), called with ExecuteCallBack AddressOf MyCallback I'm calling Pa_Openstream( .. params, Addressof MyCallBack ..) where definition of dll func is

Pa_OpenStream( .. params, PaTestCallback as Long ..)

What's the difference? What is my example missing - I'm SURE it's something stupid or obvious!

David

WaveyDavey
In the above question you defined the patestCallBack parameter of Pa_OpenStream function as IntPtr not long.
Eduard Wirch
Yeah, sorry, my bad. I'm getting ahead of myself. Still fails with long - I get 'AddressOf' expression cannot be converted to 'Long' because Long is not a delegate type
WaveyDavey
further reading implies that I need to use marshalling and delelegate methods, so I'm now more confused that ever. I wish mixed language programming were easier than this !
WaveyDavey
Try to follow the steps described in the MSDN article step by step and check if it works for you. If it does work start extending the example until you have something which is very similar to what you have now. You should get the point then.
Eduard Wirch
Eduard - this article example does not work in vb in visual studio 2005, because it raises the error above. I need to use some marshalling method I think to get a correct pointer to pass to the dll.
WaveyDavey