0

我使用 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) 运行时是否使用一些“魔术”所以调用来自正确实例的函数?

4

0 回答 0