加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

objective-c – 使NSInvocation调用一个特定的IMP

发布时间:2020-12-16 03:37:50 所属栏目:百科 来源:网络整理
导读:我正在寻找一种使NSInvocation调用特定IMP的方法.默认情况下,它调用可以找到的“最低”IMP(即最近被覆盖的版本),但是我正在寻找一种方法来使它在继承链中从更高层调用IMP.我想要调用的IMP是动态确定的,否则我可以使用超级关键字或类似的东西. 我的想法是使用
我正在寻找一种使NSInvocation调用特定IMP的方法.默认情况下,它调用可以找到的“最低”IMP(即最近被覆盖的版本),但是我正在寻找一种方法来使它在继承链中从更高层调用IMP.我想要调用的IMP是动态确定的,否则我可以使用超级关键字或类似的东西.

我的想法是使用-forwardInvocation:机制来捕获一个消息(容易且已经工作),然后改变IMP,所以它不会是超级实现也不是最远的后代的实现. (硬)

我发现远程关闭的唯一的事情是AspectObjectiveC,但这需要使用libffi,这使得它与iOS不兼容.理想情况下,我希望这是跨平台.

有任何想法吗?

免责声明:我只是在试验

尝试@ bbum的蹦床功能的想法

所以我觉得我已经有了大部分的事情.我有以下蹦床通过class_addMethod()正确添加,它确实输入:

id dd_trampolineFunction(id self,SEL _cmd,...) {
    IMP imp = [self retrieveTheProperIMP];
    self = [self retrieveTheProperSelfObject];
    asm(
        "jmp %0n"
        :
        : "r" (imp)
        );
    return nil; //to shut up the compiler
}

我已经验证了正确的自身和正确的IMP是JMP之前的正确的东西,并且_cmd参数也正确进入. (换句话说,我正确地添加了这个方法).

但是,事情正在发生.我有时会发现自己跳到一个没有自己和_cmd的方法(通常不是正确的).其他时候,我会在一个EXC_BAD_ACCESS的无处中间崩溃.想法? (已经很长时间,因为我已经完成任何程序集…)我在x86_64测试这个.

解决方法

鉴于您已经拥有IMP,您只需要一种方式来对IMP进行一个非常原始的方法调用.鉴于您愿意使用像NSInvocation一样的解决方案,那么您还可以构建类似的代理类.

如果我面对这个,我将创建一个简单的代理类,其中包含要调用的IMP和目标对象(您需要设置自身参数).然后,我将在汇编中编写一个蹦床函数,它接受第一个参数,假设它是代理类的一个实例,抓住自己,将其填充到保存参数0的寄存器中,将IMP和* JMP作为尾部呼叫.

随着蹦床在手,你会添加该蹦床作为任何选择器上的代理类,您希望转发到一个特定的IMP ….

为了实现任何类型的通用机制,关键是避免与重写栈帧有关的任何事情.避免C ABI.避免移动争论.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读