I'm using PortAudioSharp as a C# wrapper for PortAudio (PA). However the question is more general, so I will strip the code a bit for clarity.
PA has a callback, that is invoked when it needs new data. So opening a stream will use this function:
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate PaStreamCallbackResult PaStreamCallbackDelegate(IntPtr input, IntPtr userData);
[DllImport("PortAudio.dll")]
public static PaError Pa_OpenStream(out IntPtr stream, PaStreamCallbackDelegate streamCallback, IntPtr userData);
I now have a class, that runs a decoder filling a buffer in that class. I want PA to call back a function from that class to get new data. Code is this:
class CFoo{
private PaStreamCallbackDelegate _PaStreamCallback;
void Open(){
_PaStreamCallback = _ProcessNewData;
IntPtr myStream;
Pa_OpenStream(out myStream, _PaStreamCallback, IntPtr.Zero);
}
private PaStreamCallbackResult _ProcessNewData(IntPtr input, IntPtr userData){
var buf = new byte[SIZE];
// Fill buf ... and then:
Marshal.Copy(buf, 0, output, buf.Length);
return PaStreamCallbackResult.paContinue;
}
}
This seems to work so far. Problem: Sometimes when there is more than 1 stream (1 paused, 1 running) the callback of the wrong stream gets called. I think, the delegate might be the problem.
So questions:
1) Is the above correct? Can I just pass a member function as a delegate to C++?
2) How does this work? If it were C++ instead of C# one would have to make a C detour function, that will convert the userData Pointer into a class and then call the class callback (e.g. ((CFoo*) userData)->_ProcessNewData) Does the runtime use some "magic" so the function from the right instance is called?