gpt4 book ai didi

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

转载 作者:太空狗 更新时间:2023-10-30 03:21:28 27 4
gpt4 key购买 nike

是我之前问题的后续: What are the digits in an ObjC method type encoding string?

假设有一个编码:

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 不保证在优化时参数寄存器将跨调用边界保留。你不得不开始组装,事情变得非常丑陋真的很快(>颤抖<)。

关于objective-c - ObjC 方法类型编码中的数字是如何计算的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11527385/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com