如何使用 Dart ffi 表示具有 int 和 string 声明的 ObjC enum AVAudioSessionPortOverride?

How to represent ObjC enum AVAudioSessionPortOverride which has declaration of int and string using Dart ffi?

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

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

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

在执行此操作时,我们遇到了 AVAudioSessionPortOverride 枚举,它有两个声明; AVAudioSessionPortOverrideSpeaker = 'spkr'AVAudioSessionPortOverrideNone = 0.

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

我注意到 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' 实际上是一个整数。参见例如 了解 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