对 SIMD 类型和将它们用于 Objective-C 运行时的函数进行编码的正确方法是什么?

What is the proper way to encode SIMD types and functions that use them for the Objective-C Runtime?

我正在使用 Objective-C 以外的语言开发应用程序,我遇到了 newBoxWithDimensions。它使用来自 SIMD API.

vector_float3 类型

由于 vector_float3 类型,我无法对这个函数进行编码。

我找到了Why can't gcc or clang properly @encode SIMD vector types?;这里的问题是当 @encode 没有对 SIMD 类型进行编码时,它就无法为那些使用 SIMD 类型的函数创建合适的形式,然后消息发送验证失败。如何在消息发送验证中绕过这个编码问题?

作为实验,我请求了 +newBoxWithDimensions:segments:geometryType:inwardNormals:allocator: 的方法签名,使用:

NSMethodSignature* sig = [MDLMesh methodSignatureForSelector:@selector(newBoxWithDimensions:segments:geometryType:inwardNormals:allocator:)];

然后我列举了它的参数和它们的类型编码。事实证明,签名只是跳过了两个向量参数。它显示了总共 5 个参数,其中包括隐式 self_cmd 参数,而应该有 7 个。编码是“@”、“:”、"q"、"c", "@",前两个对应self_cmd,后三个对应方法的最后三个参数

我认为最安全的方法是编写一个 Objective-C 模块,该模块导出一个包装此方法的函数,但向量分量单独传递(即三个 float 维度参数和三个 unsigned int 段的参数)。它将根据这些单独的参数构造矢量参数并调用 class 方法,返回其结果。

Rust 的解决方案

对于那些使用 Rust 并遇到同样问题的人,我找到了绕过错误的解决方法,但请记住问题仍然存在,我的解决方案会使开发人员在调试过程中变得盲目。

  • 如果您使用的是 objc crate,请尝试从您的 crate 中删除 verify_message 功能,否则不要进行消息验证。
  • 使用 simd 表示您的矢量数据,并在不进行任何编码的情况下将您的数据放入您的消息中。
  • 在这种情况下,您的开发非常盲目,我建议的一种方法是将您的调试纳入 Xcode(这也不好!)。