我正在使用PortAudioSharp作为PortAudio(PA)的C#包装器。然而问题是更一般的,所以为了清楚起见,我将略微删除代码 PA有一个回调函数,在需要新数据时调用它。因此,打开流将使用此功能:
[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);
我现在有一个类,它运行一个解码器来填充该类中的缓冲区。我希望PA从该类中回调函数以获取新数据。代码是这样的:
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;
}
}
到目前为止这似乎有效。问题:有时当有超过1个流(暂停1次,1次运行)时,将调用错误流的回调。我认为,代表可能是问题所在。
所以问题:
1)以上是否正确?我可以将成员函数作为委托传递给C ++吗?
2)这是如何工作的?如果它是C ++而不是C#,则必须创建一个C绕行函数,将userData指针转换为类,然后调用类回调(例如((CFoo *)userData) - > _ProcessNewData)运行时是否使用一些“魔法”所以来自右边实例的函数被称为?