如何使用Dart ffi表示具有int和字符串声明的ObjC枚举AVAudioSessionPortOverride?

问题描述

我正在为Flutter开发跨平台声音API。 我们正试图停止对API的iOS部分使用Objective C / Swift,而使用Dart ffi作为替代。

ffi(外部函数接口)允许dart调用Obj C API。

这意味着我们需要创建一个封装Obj C音频库的dart库。

这样做的时候,我们遇到了AVAudioSessionPortOverride枚举,它有两个声明; AVAudioSessionPortOverrideSpeaker = 'spkr'AVAudioSessionPortOverrideNone = 0

我对这里发生的事情感到困惑,因为其中一个声明是一个整数,而另一个是字符串。

我注意到AVAudioSessionPortOverride扩展了NSUInteger,因此如何处理字符串。是否以某种方式转换为int?如果有的话,关于如何在dart中执行此操作的任何想法?

这是我们到目前为止的内容

class AVAudioSessionPortOverride extends NSUInteger {
  const AVAudioSessionPortOverride(int value) : super(value);

  static AVAudioSessionPortOverride None = AVAudioSessionPortOverride(0);

  static const AVAudioSessionPortOverride Speaker =
      AVAudioSessionPortOverride('spkr');
}

解决方法

'spkr'实际上是一个整数。参见例如How to convert multi-character constant to integer in C?解释了C中这种晦涩的功能是如何工作的。

也就是说,如果您查看PortOverride枚举的Swift表示形式,则会看到以下内容:

/// For use with overrideOutputAudioPort:error:
public enum PortOverride : UInt {    
    /// No override.  Return audio routing to the default state for the current audio category.
    case none = 0

    /// Route audio output to speaker.  Use this override with AVAudioSessionCategoryPlayAndRecord,/// which by default routes the output to the receiver.
    case speaker = 1936747378
}

另外,请参见https://developer.apple.com/documentation/avfoundation/avaudiosession/portoverride/speaker

因此,01936747378是您应该使用的值。

,

看看这个

NSLog(@"spkr = %x s = %x p = %x k = %x r = %x",'spkr','s','p','k','r' );

Apple正在做您的讲师警告您的所有事情。您可以避免这种情况,因为字符串的长度为4个字符(字节)。如果您将其延长,则会收到警告。如上面的代码片段所示,字符串将转换为int。您可以通过一个接一个地访问四个字节并将其打印为字符来反转它。

扰流板-它会打印

spkr = 73706b72 s = 73 p = 70 k = 6b r = 72