繁体   English   中英

如何计算ObjC方法类型编码中的数字?

[英]How are the digits in ObjC method type encoding calculated?

是对我上一个问题的后续跟踪: ObjC方法类型编码字符串中的数字是什么?

说有一个编码:

v24@0:4:8@12B16@20

这些数字是如何计算的? B是一个字符,所以它应该只占用1个字节(而不是4个字节)。 它与“对齐”有关吗? void的大小是多少?

如下计算数字是否正确? 在每个项目上询问sizeof并将结果四舍五入为4的倍数? 第一个数字成为所有其他数字的总和?

这些数字在m68K天用于表示堆栈布局。 也就是说,您可以逐字解码方法签名,对于几乎所有类型,确切地知道堆栈帧中哪些偏移量可以用来获取/设置参数。

这是有效的,因为m68K的ABI完全是[IIRC--已经很长时间]基于堆栈的参数/回传。 跨越呼叫边界没有任何东西被塞进寄存器中。

但是,当Objective-C被移植到其他平台时,堆栈中的永远不再是调用约定。 参数和返回值通常在寄存器中传递。

因此,那些抵消现在是无用的。 同样,编译器使用的类型编码也不再完整(因为它从未非常有用),并且会有类型不会被编码。 没有提及编码一些C ++模板化类型会产生方法类型编码字符串,其大小可以是多千字节(我认为我遇到的记录大约是30K的类型信息)。

所以,不,使用sizeof()生成数字是不正确的,因为它们对所有事物都毫无意义。 它们仍然存在的唯一原因是二进制兼容性; 这里和那里有一些深奥的代码仍在解析类型编码字符串,期望会有随机数字洒在这里和那里。

请注意,ObjC运行时中存在API的残余,这仍然使人们相信可以动态编码/解码堆栈帧。 实际上并不是因为C ABI不能保证在优化过程中跨越调用边界保留参数寄存器。 你必须下降到组装事情变得丑陋真的快(>不寒而栗<)。

完整的编码字符串由方法ASTContext::getObjCEncodingForMethodDecl构建(在clang中),您可以在lib/AST/ASTContext.cpp找到lib/AST/ASTContext.cpp

执行大小舍入的方法是ASTContext::getObjCEncodingTypeSize ,在同一文件中。 它强制每个大小至少为int的大小。 在Apple的所有当前平台上, int是4个字节。

堆栈帧大小和参数偏移量由编译器计算。 我本周试图在Clang来源中追踪这个问题。 它可能与CodeGenTypes::arrangeObjCMessageSendSignature (看起来Rob让我的生活变得更轻松!)

第一个数字是其他数字的总和,是 - 它是参数占用的总空间。 要在代码中获取由ObjC类型编码表示的类型的大小,您应该使用NSGetSizeAndAlignment()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM