首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

如何在现代OS X版本上从C调用objc_msgSend

在现代OS X版本上,可以通过以下步骤从C语言中调用objc_msgSend函数:

  1. 引入必要的头文件:
代码语言:txt
复制
#include <objc/objc.h>
#include <objc/message.h>
  1. 定义一个函数指针来指向objc_msgSend函数:
代码语言:txt
复制
typedef id (*MsgSendFunction)(id, SEL, ...);
  1. 获取objc_msgSend函数的地址:
代码语言:txt
复制
MsgSendFunction msgSend = (MsgSendFunction)objc_msgSend;
  1. 创建一个Objective-C对象并调用方法:
代码语言:txt
复制
id object = objc_getClass("ClassName");
SEL selector = sel_registerName("methodName");
id result = msgSend(object, selector, arg1, arg2, ...);

其中,ClassName是要调用方法的类名,methodName是要调用的方法名,arg1arg2等是方法的参数。

  1. 处理返回值: 根据方法的返回类型,对result进行适当的类型转换。

这样,就可以在现代OS X版本上从C语言中调用objc_msgSend函数了。

请注意,以上步骤仅适用于OS X平台上的Objective-C代码。在其他平台或使用其他编程语言时,可能需要采用不同的方法来调用Objective-C方法。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

Runtime 中的消息机制

说道Objective-C里面的消息机制,大部分人都知道是调用方法其实就是发送消息,一个叫objc_msgSend的东西负责的。...今天结合《编写高质量iOS与OS X代码的52个有效方法》趴一趴消息机制。...Objective-C是在C的基础,借鉴 Smalltalk 的面向对象与消息机制扩展出来的语言,就像Golang语言天生自带并发基因。...说过了OC的函数调用实现,你会觉得消息转发要处理很多,尤其是在搜索,幸运的是objc_msgSend在搜索这块是有做缓存的,每个OC的类都有一块这样的缓存,objc_msgSend会将匹配结果缓存在快速映射表...写在最后 《编写高质量iOS与OS X代码的52个有效方法》是一本很不错的书,想在OC做的深的一点话,最好看看这本书,必会有不少收益

1K50

runtime

术语 1、Objective-C runtime包括两个版本,Modern Runtime和 Legacy Runtime: Modern Runtime(现代的Runtime):64 位的 Mac OS...X 应用和所有 iPhone OS 的应用 Legacy Runtime: 所有 32 位的 Mac OS X 应用 2、Method 有 2 种基本类型的方法: Instance Method(实例方法...- (NSString *)movieTitle 3、Selector Selector 在 Objective-C 中 selector 只是一个 C 的数据结构,用于表示一个你想在一个对象执行的...version:类的版本信息。 info:运行期使用的标志位,比如0x1(CLS_CLASS)表示该类为普通class,0x2(CLS_META)表示该类为 metaclass。...所以当 objc_msgSend() 在一个类中查找 selector 时会先查找类缓存。有个理论是,当你在一个类上调用了一个消息,你很可能之后还会调用它。

65520
  • iOS底层原理之Runimte 运行时&方法的本质

    Runtime版本 Runtime有两个版本,一个Legacy版本(早期版本),一个Modern版本(现行版本) 早期版本对应的编程接口:Objective-C 1.0 现行版本对应的编程接口:Objective-C...2.0,源码中经常看到的OBJC2 早期版本用于Objective-C 1.0,32位的Mac OS X的平台 现行版本用于Objective-C 2.0,iPhone程序和Mac OS X v10.5...子类的对象可以调用父类的方法。 猜想:方法调用,首先在本类中找,如果没有就到父类中找。 objc_msgSend汇编探究 探究objc_msgSend首先找到objc_msgSend所在的底层库。...必须拿出yysd-汇编 汇编显示objc_msgSend在libobjc.A.dylib系统库,实际objc_msgSend前缀是objc猜测应该在 objc源码中。...在objc源码中全局搜索objc_msgSend,找到真机的汇编objc-msg-arm64.s objc_msgSend汇编入口 下面的汇编会用到p0-p17,大家可能对汇编中x0,x1比较熟悉知道是寄存器

    36810

    手把手教你查看和分析iOS的crash崩溃异常

    苹果自身也构建了一套crash采集和分析的机制,你可以真机的联机日志或者开发者账号中去查看对应的crash信息。网络也有很多关于crash分析的文章,以及crash堆栈符号化处理的文章。...崩溃的函数调用栈中可以看出异常是出现在最顶层的函数调用objc_msgSend+16处,也就是在objc_msgSend函数的第5条指令处(通常情况下arm体系结构中每条指令占用4个字节,上述的信息表明是崩溃在函数的第...objc_msgSend的部分实现代码。...你可以在崩溃异常报告的: OS Version: iOS 10.3.3 (14G60) 部分看到产生异常的操作系统版本号,就如本文的例子里面产生异常的操作系统版本号为iOS 10.3.3。...如果产生崩溃的栈顶是一个通用的C函数比如objc_msgSend、free、objc_release则考虑用函数调用栈的第二层函数和方法名来设置符号断点。

    6K31

    iOS开发·runtime原理与实践: 消息转发篇(Message Forwarding) (消息机制,方法未实现+API不兼容奔溃,模拟多继承)

    选择器本质就是不透明的字符串,它们被管理,因此可以使用简单的指针相等来比较它们,从而提高速度。(实现可能会有所不同,但这基本是他们在外部看起来的样子。)...1.1 方法与消息发送 消息在OC中方法调用是一个消息发送的过程。OC方法最终被生成为C函数,并带有一些额外的参数。这个C函数objc_msgSend就负责消息发送。...objc_msgSend(id _Nullable self, SEL _Nonnull op, ...)` 1.2 消息发送的主要步骤 消息发送的时候,在C语言函数中发生了什么事情?...比如Mac OS X开发,有了垃圾回收就不会理会retain,release这些函数。...在编译时你写的 OC 函数调用的语法都会被翻译成一个 C 的函数调用 objc_msgSend() 。

    2K11

    objc_msgSend 实现分析

    1.2 runtime 版本 Runtime 有两个版本:Legacy 版本(早期版本,对应 Objective-C 1.0) 和 Modern 版本(现行版本 Objective-C 2.0)。...早期版本:用于 Objective-C 1.0, 32 位的 Mac OS X 的平台。 现行版本:iPhone 程序和 Mac OS X v10.5 及以后的系统中的 64 位程序。...modern 版本最显著的变化就是 non-fragile: legacy 版本,如果你改变类中的实例变量的布局,必须它继承的类重新编译。...:objc_msgSend(消息接收者,消息的主体(sel + 参数)) 1.4.1 objc_msgSend 那么就意味着我们自己也可以通过 objc_msgSend 调用方法,为了方便去掉参数调用...2. cache读取流程分析 一篇文章中分析 cache 的调用时机是确认了如下调用顺序:__objc_msgSend_uncached(汇编)->lookUpImpOrForward->log_and_fill_cache

    88830

    iOS进阶之传递消息

    、理解objc_msgSend的作用 对象上调用方法用OC的术语,叫做“传递消息”。消息有名称或选择子,可以接受参数,而且可能还有返回值。 先理解C语言的函数调用方式。...当然啦,这种“快速执行路径”(fast path)还是不如“静态绑定的函数调用操作”那样迅速,不过只要把选择子缓存起来了,也就不会慢很多,实际,消息派发并非应用程序的瓶颈所在。...这项优化对objc_msgSend非常关键,如果不这么做的话,那么每次调用Objective-C方法之前,都需要为调用objc_msgSend函数准备“栈帧”,大家在“栈踪迹”中可以看到这种“栈帧”。...这样的话,你就会明白,在发送消息时,代码究竟是如何执行的,而且也能理解,为何在调试的时候,栈“回溯”信息中总是出现objc_msgSend。 要点 1️⃣消息由接受者、选择子及参数构成。...给某对象“发送消息”(ivoke a message)也就相当于该对象调用方法”(call a method)。

    76960

    深入浅出 Runtime(三):消息机制

    1. objc_msgSend 方法调用流程 在OC中调用一个方法时,编译器会根据情况调用以下函数中的一个进行消息传递:objc_msgSend、objc_msgSend_stret、objc_msgSendSuper...其他方法调用的情况都是转换为objc_msgSend()函数的调用。 void objc_msgSend(id _Nullable self, SEL _Nonnull op, ...)...在底层汇编里面如果需要调用 C 函数的话,苹果会为其加一个下划线_, 所以查看objc_msgSend函数的实现,需要搜索_objc_msgSend(objc-msg-arm64.s(objc4))。...方法会在类第一次接收到消息时调用 // 调用方式:objc_msgSend() // 调用顺序:先调用父类的 +initialize,再调用子类的 +initialize (先初始化父类...以下是网上找到的___forewarding___的 C 语言伪代码实现。

    76430

    runtime的那些事(一)——runtime基础介绍

    都说 Objective-C 是一门动态语言。首先,动态与静态语言最大的区别,就是动态语言将数据类型的检查等决策尽可能地程序编译时推迟到了运行时。只要有可能,runtime 就会动态地完成任务。...runtime 是一套用C语言提供的 API,Objective-C 代码最终都会被编译器转化为运行时代码,通过消息机制决定了不同函数调用或转发方式,因此 runtime成为了 Objective-C...---- 二、runtime 版本 runtime 目前共有两个版本, Legacy 与 Modern 版本,与之相对应的编程接口分别是 Objective-C 1.0 与 2.0。...Legacy 版本主要用于32位的Mac OS X平台上开发,而 Modern 版本用于 iPhone 程序与 Mac OS X 10.5以及更新版本系统中的64位程序。...的C函数转化后,可以发现: 所有的 Objective-C 方法调用都会在编译时转化成C函数 objc_msgSend调用 objc_msgSend 方法一定会有两个参数:消息接收者、消息方法名称

    1.4K20

    iOS开发 —— Runtime

    Runtime 因为Objc是一门动态语言,所以它总是想办法把一些决定工作编译连接推迟到运行时。...苹果和GNU各自维护一个开源的runtime版本,这两个版本之间都在努力的保持一致。 消息传递 在很多语言中,比如C调用一个方法其实就是跳到内存中的某一点并开始执行一段代码。...事实,在编译时,我们所编写的 Objective-C 函数都会被翻译成一个C语言的函数调用。 - objc_msgSend(id self, SEL op, ...)。...消息传递的过程 在 Objective-C 中,类、对象和方法都是一个 C 的结构体, objc/objc.h 头文件中,我们可以找到他们的定义。...NSInvocation 实际就是对一个消息的描述 ,包括方法名以及参数等信息。

    1.2K30

    objc_msgSend底层探索(下)

    一篇里面,我OC层面来探索了objc_msgSend如何进行消息的发送,对普通开发者来说也是比较容易理解的,那很多人都知道,Runtime是由C或者C++以及汇编语言写的一套底层的API。...通常来说我都只会去分析一下C或者C++的源码,因为还是能够勉强看懂的,而很少去了解或者看到过汇编,那现在就到了需要感受一下汇编的时候了,而汇编又是怎么objc_msgSend引出来的呢?...就是进入的意思,往往就是一个函数的开始,我点进去,最直观的感受就是,他的实现代码量很少,感觉很简单。 这里先插一个问题,为什么objc_msgSend是用汇编写的?而不是用C/C++写呢?...我刚刚随便一搜索就搜到了很多的objc_msgSend。 也就是说,源码里面包含了多个版本objc_msgSend方法,他们是根据返回值的类型和调用者的类型分别处理的,如果说用C或者C++来实现。...接下来175行就直接br,跳转返回到imp并且对imp进行调用,也就是说,从缓存里面找到之后就直接调用,这就是objc_msgSend函数在底层通过 sel 去找 imp 的一个过程,到这里就全部疏通了

    21320

    C++与Objective-C混编

    在一些iOS开发中,经常有一些第三方的框架是用C++写的,有时候我们需要在C++文件中调用OC方法,或者在OC文件中调用C++函数,也就是C++与Objective-C混编。...Objective-C++ C函数桥接 运行时 一、通过Objective-C++ Objective-C++是C++的超集,就如同Objective-CC的超集,在OS X同时被GCC和Clang...支持编译,能够不用C++来初始化OC对象和调用方法。...MyClass c; double seconds = c.secondsSince1970(); 二、通过C函数来桥接 我们知道Objective-CC++都是在C语言的基础发展而来的语言,都能同时支持...,从而达到混编的目的 三、运行时objc_msgSend 一提到将OC方法变成C函数,肯定会想到运行时,在Objective-C中,消息在运行时才被绑定到方法实现。

    1.4K20

    iOS - Dissecting objc_msgSend on ARM64

    因此,在 objc_msgSend 查找的时候,会遵循以下几点: 1、获取传入对象的类 2、类中获取方法的缓存 3、使用传入的 selector 来在缓存中寻找方法 4、如果没在缓存中,调用 C 的方法...ldp 命令将两个寄存器的数据内存加载到两个参数命名的寄存器中。第三个参数描述了哪里来读取数据,在这种情况下是 x16 的值再偏移 16 位,这里存放着类的缓存信息。...当所有的信息被缓存之后,在现代的硬件这个路径的执行时间不到3纳秒。 这就是快速路径,剩下的代码怎么办呢?让我们继续看看没有匹配上的 bucket。...之前的一个版本objc_msgSend 错误的处理了它 - 它立即终止而不是返回到 C 代码中,这样做运气不好的话会发生罕见的崩溃. 0x0060 ldp x9, x17, [x12, #...所有对于 nil 的处理就是返回给调用者 0。 这实际对于那些关心返回值是什么的调用者来说会有些麻烦因为 objc_msgSend 不知道返回的是什么值。

    65040

    iOS16 和 Xcode14 如何改进 App 大小和运行时性能

    概要: 本文主要介绍苹果在 Xcode14 和 iOS 16 ,如何编译层面和运行时层面,优化 Swift 和 Objective-C runtime, 来让 app 二进制体积更小,运行更快,启动更快...使用 Xcode 14 的编译器和链接器,可以让 ARM64 的消息发送调用 12 字节降低到 8 字节。消息发送无处不在,这个优化可以让二进制文件的代码大小降低 2%左右。...由于是 Objective-C 中消息发送机制,每个方法调用都走 _objc_msgSend 方法: // Method calls using objc_msgSend...比如上述调用会转化类似这样: objc_msgSend(cal, @selector(dateFromComponents)) 当我们查看二进制文件时,这些指令的每一条都会耗费一些空间,在 ARM64...在 Xcode14 编译器,retain/release 在 ARM64 上调用 8 个字节降到 4 个字节。就像一章节中消息发送一样,retain/release 也是无处不在。

    3.9K30

    RunTime 之使用前须知

    也就是说 IMP 是消息最终调用的执行代码,是方法真正的实现代码 。我们可以像在C语言里面一样使用这个函数指针。...(比如.h中声明了方法,但.m中没有实现,就可以重现这个错误) 在 Objective-C 语言中,每一个类实际也是一个对象。每一个类也有一个名为 isa 的指针。...另外objc_msgSend方法也能hold住message的参数,objc_msgSend(receiver, selector, arg1, arg2, …); OC的动态特性 OC在底层也提供了相当丰富的运行时的特性...调用一个实例的方法,所做的是向该实例的指针发送消息,实例在收到消息后,自身的实现中寻找响应这条消息的方法。 动态绑定所做的,即是在实例所属类确定后,将某些属性和相应的方法绑定到实例。...动态加载 根据需求加载所需要的资源,最经典的例子就是在Retina设备加载@2x的图片,而在老一些的普通屏设备加载原图。

    72820

    深入解构objc_msgSend函数的实现

    objc_class(Class对象)结构简介 熟悉OC语言的Runtime(运行时)机制以及对象方法调用机制的开发者都知道,所有OC方法调用在编译时都会转化为对C函数objc_msgSend调用。...objc_class结构体中的数据成员非常的多也非常的复杂,这里并不打算深入的去介绍它,本文主要介绍的是objc_msgSend函数内部的实现,因此在下面的代码中将会隐藏大部分数据成员的定义,并在不改变真实结构体定义的基础只列出...objc_msgSend函数的内部实现 objc_msgSend函数是所有OC方法调用的核心引擎,它负责查找真实的类或者对象方法的实现,并去执行这些方法函数。...}; /* objc_msgSendC语言版本伪代码实现. receiver: 是调用方法的对象 op: 是要调用的方法名称字符串 */ id objc_msgSend(id receiver...这部分的实现代码如下: //设置更新缓存的哈希桶内存和mask值。

    95320

    静态拦截iOS对象方法调用的简易实现

    对于静态插桩的实现一般有如下两个方案: 借助于LLVM语法树分析来实现代码插桩。 将源码编译为静态库,并通过修改静态库中.o目标文件的代码段来实现代码插桩。...这个函数必须要和objc_msgSend的函数签名保持一致,这样在链接时所有静态库中的objc_msgSend调用都会统一转化为hook_msgSend调用。 下面的是具体的实现步骤: 1....至于这个符号替换程序如何编写则没有限制,你可以用ruby编写也可以用python也可以用C语言编写。 无论用何种方法实现,你都需要首先了解一下静态库.a的文件结构。...你可以:《深入iOS系统底层之静态库》一文中掌握到一个静态库文件的组成结构。了解了静态库文件的组成结构后,你的符号替换程序要做的事情就可以按如下步骤实现: 一)、 打开静态库.a文件。...因此这种技术不仅可以应用代码重排统计,还可以应用在其他的监控和统计应用中。因为这种机制可以避免程序在运行时进行objc_msgSend替换而产生的函数调用风暴问题。

    1.8K30
    领券