那是古老的 Mac 程序员早已死去的技术,最好保持原状。但是,如果你有兴趣,我们就出发吧,勇敢的冒险家!
这里是直接来自Apple的相关#define-s:
#define ONEWORDINLINE(w1) = w1
#define TWOWORDINLINE(w1,w2) = {w1,w2}
#define THREEWORDINLINE(w1,w2,w3) = {w1,w2,w3}
/* ...etc... */
#define TWELVEWORDINLINE(w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12) = {w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12}
现在来解释一下。
一点历史教训:早在 Mac 为(同样古老的)Motorola 68k 实现的远古时代,Apple 在以下高度紧凑且非常有用中设置了它的系统调用> 方式:他们将它们映射到以1010b (0xA) 开头的单词,因为它们被摩托罗拉开发人员保留用于此用途。这些系统调用及其映射被称为此十六进制值的 A-Trap(老实说,与 “这是一个陷阱!” 无关)。它们在十六进制中看起来像这样:0xA869(此示例是 FixRatio(short numer, short denom) 系统调用的 A-Trap)。这项技术最初是为Mac Toolbox API 创建的。
当 Mac-on-68k-targeting 编译器(这些应该将 TARGET_OS_MAC 和 TARGET_CPU_68K 宏设置为 1 或 TRUE 和 TARGET_RT_MAC_CFM 为 0 或 FALSE,顺便说一句)看到一个带有赋值 (=) 的函数原型,它将原型视为引用由赋值运算符右侧的 A-Trap 值指示的 A-Trap 系统调用,它可以是单个整数文字-以0xA (0xA???) 开头的字值。所以,ONEWORDINLINE 基本上是一种时尚的宏观方式,表示“它是一个 A-Trap!”。
所以,下面是 68k 的系统调用函数原型声明的样子:
EXTERN_API(Fixed) FixRatio(short numer, short denom) ONEWORDINLINE(0xA869);
这会被预处理成这样的:
extern Fixed FixRatio(short numer, short denom) = 0xA869;
现在,您可能会想:如果我们按一个词索引系统调用,而该词的四分之一被巨大的 0xA 占用,那么最多只有 4096 个函数(有 实际上要少得多,因为许多 A-Trap 实际上映射到相同的系统调用子例程,但具有不同的参数),这还不够吗?好吧,显然不是。这就是 选择器 发挥作用的地方。
像_HFSDispatch (0xA260) 这样的A-Trap 被称为“选择器”,因为它们的工作是选择 并调用由堆栈上的值确定的另一个子例程。因此,当一个函数原型被“分配”了一个单字整数文字的“数组”时,除了最后一个(称为选择器代码)之外的所有东西都被压入堆栈,并且最后一个被视为一个 A-Trap 选择器,它抓取压入堆栈的单词并调用适当的子例程。这样一个数组中的最大单词数是 12,因为这对于 Mac 工具箱来说已经足够了。
宏 TWOWORDINLINE 到 TWELVEWORDINLINE 处理选择器 A-Trap。例如:
EXTERN_API(OSErr) ActivateTSMDocument(TSMDocumentID idocID) TWOWORDINLINE(0x7002, 0xAA54);
会被预处理成类似的东西
extern OSErr ActivateTSMDocument(TSMDocumentID idocID) = {0x7002, 0xAA54};
这里,0x7002 是选择器代码,0xAA54 是选择器 A-Trap。
因此,总而言之,如果您想为在摩托罗拉 68k 上运行的 1994 年以前的 Mac-s 进行一些编码,您只需要它。所以ios 在这里并不存在;)
免责声明:我只在理论上知道这些东西,我可能在某个地方犯了错误。如果有老手有这方面的经验,有不对的地方还请指正!