我一直想知道我能用这样的东西做什么:
ONEWORDINLINE(w1)
TWOWORDINLINE(w1, w2)
THREEWORDINLINE(w1, w2, w3)
直到
TENWORDINLINE(w1, w2, w3, w4, w5, w6, w7, w8, w9, w10)
ELEVENWORDINLINE(w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11)
TWELVEWORDINLINE(w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12)
答案 0 :(得分:10)
以下是来自Apple的相关#define
- :
#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在以下高度紧凑且非常实用的<中设置了系统调用/ em>方式:他们将它们映射到以1010b
(0xA
)开头的单词,因为它们是由摩托罗拉开发者保留用于此用途的。这些系统调用及其映射称为此十六进制值的A-Traps(与“IT'S A TRAP!无关),老实说)。它们看起来像十六进制:0xA869
(此示例是FixRatio(short numer, short denom)
系统调用的A-Trap)。该技术最初是为Mac Toolbox API创建的。
当Mac-on-68k定位编译器(这些应将TARGET_OS_MAC
和TARGET_CPU_68K
宏设置为1
或TRUE
和TARGET_RT_MAC_CFM
为{ {1}}或0
,BTW)在它之后看到一个带有赋值(FALSE
)的函数原型,它将原型视为引用由A-Trap值指示的A-Trap系统调用在赋值运算符的右侧,可以是以=
(0xA
)开头的单个整数字面单字值。因此,0xA???
基本上是一种时髦的宏观方式,说“它是 A-Trap!”。
所以,这是68k的sys-call函数原型声明的样子:
ONEWORDINLINE
这将被预处理为这样的事情:
EXTERN_API(Fixed) FixRatio(short numer, short denom) ONEWORDINLINE(0xA869);
现在,你可能会想:如果我们用一个单词索引系统调用,并且巨大的extern Fixed FixRatio(short numer, short denom) = 0xA869;
占用该单词的四分之一,那么最多只有4096个函数(有很多实际上很少,因为许多A-Traps实际上映射到相同的系统调用子程序,但是具有不同的参数),这是怎么回事?嗯,显然,事实并非如此。这就是选择器的用武之地。
像0xA
(_HFSDispatch
)这样的陷阱被称为“选择器”,因为他们有选择并调用由堆栈上的值确定的另一个子例程。因此,当函数原型被“分配”一个单词整数文字的“数组”时,除了最后一个(称为选择器代码)之外的所有文件都被推入堆栈,并且最后一个被视为一个A-Trap选择器,它抓住了压入堆栈的单词并调用了相应的子程序。这样一个数组中的最大单词数是12,因为这足以支持Mac工具箱。
宏0xA260
到TWOWORDINLINE
处理了选择器A-Traps。例如:
TWELVEWORDINLINE
将被预处理为类似
的内容EXTERN_API(OSErr) ActivateTSMDocument(TSMDocumentID idocID) TWOWORDINLINE(0x7002, 0xAA54);
此处,extern OSErr ActivateTSMDocument(TSMDocumentID idocID) = {0x7002, 0xAA54};
是选择器代码,0x7002
是选择器A-Trap。
所以,总而言之,如果你想为1994年以前在摩托罗拉68k上运行的Mac-s做一些编码,你只需要它。所以ios在这里并没有真正到位;)
免责声明:我在理论上只知道这些东西,我可能在某处犯了错误。如果有这些东西有经验的老人,如果我出错了,请纠正我!