Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >C++与Objective-C混编

C++与Objective-C混编

作者头像
Helloted
发布于 2022-06-08 02:23:11
发布于 2022-06-08 02:23:11
1.8K00
代码可运行
举报
文章被收录于专栏:HellotedHelloted
运行总次数:0
代码可运行

在一些iOS开发中,经常有一些第三方的框架是用C++写的,有时候我们需要在C++文件中调用OC方法,或者在OC文件中调用C++函数,也就是C++与Objective-C混编。但是我们知道在纯OC文件中是不能编译C++代码的,在纯C++文件中又是不能编译Objective-C代码的。直接引入编译不过会报错

如果要同时混编,就要利用下面的几种方式。

  • Objective-C++
  • C函数桥接
  • 运行时
一、通过Objective-C++

Objective-C++是C++的超集,就如同Objective-C是C的超集,在OS X上同时被GCC和Clang支持编译,能够不用C++来初始化OC对象和调用方法。只要在C ++模块的实现中隐藏Objective-C header导入和类型,它就不会感染任何“纯”C ++代码。

.mm是Objective-C++的默认后缀名,Xcode会自动识别。在.mm文件中,Objective-C代码和C++代码都可以正常编译运行。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//MyClass.h
class MyClass
{
  public:
    double secondsSince1970();
};


//MyClass.mm
#include "MyClass.h"
#import <Foundation/Foundation.h>

double MyClass::secondsSince1970()
{
  return [[NSDate date] timeIntervalSince1970];
}


//Client.cpp
...
MyClass c;
double seconds = c.secondsSince1970();

二、通过C函数来桥接

我们知道Objective-C和C++都是在C语言的基础上发展而来的语言,都能同时支持C函数,所以我们可以通过C函数来桥接,从而能够编译。

先定义一个.h文件:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//CppOCBridge.h
typedef void (*interface) (void* caller,void* parameter);

自定义一个OC类

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//  TargetOC.h

#import <Foundation/Foundation.h>
#import "CppOCBridge.h"

@interface TargetOC : NSObject

- (void)doFirstMethodWith:(void*)parameter;
- (void)doSecondMethodWith:(void *)parameter;

@property interface doFirstMethod;
@property interface doSecondMethod;

@end
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//  TargetOC.m

#import "TargetOC.h"

void OcObjectDoFirstMethodWithWith(void *ocInstance, void *parameter){
    [(__bridge id)ocInstance doFirstMethodWith:parameter];
}

void OcObjectDoSecondMethodWithWith(void *ocInstance, void *parameter){
    [(__bridge id)ocInstance doSecondMethodWith:parameter];
}

@implementation TargetOC

-(instancetype)init{
    if ([super init]) {
        _doFirstMethod = OcObjectDoFirstMethodWithWith;
    }
    return self;
}

-(void)doFirstMethodWith:(void *)parameter{
    NSLog(@"oc doFirstMethodWith parameter==== %@",parameter);
}

- (void)doSecondMethodWith:(void *)parameter{
    NSLog(@"oc doSecondMethodWith parameter==== %@",parameter);
}

@end

那么,在一个C++类里,如果我们要调用一个方法的话,我们定义一个类ObjectCpp

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void ObjectCpp::call_oc_function(void *ocObj, interface function, void *parameter){
    function(ocObj,parameter);
}

调用OC方法的步骤为

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    TargetOC *ocObj = [[TargetOC alloc]init];
    ObjectCpp *cpp = new ObjectCpp; 
    cpp->call_oc_function((__bridge void*)ocObj,ocObj.doFirstMethod,(__bridge void*)@"this is paras");

OC对象和方法都被包装成一个参数来进行调用,从而达到混编的目的

三、运行时objc_msgSend

一提到将OC方法变成C函数,肯定会想到运行时,在Objective-C中,消息在运行时才被绑定到方法实现。

编译器会将一个下面的一个消息表达式

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[receiver message]

转变成一个消息函数 objc_msgSend,这个函数将接收者和消息中提到的方法的名称(即方法selector)作为其两个主要参数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
objc_msgSend(receiver, selector)

消息中传递的其他参数也在 objc_msgSend被处理

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
objc_msgSend(receiver, selector, arg1, arg2, ...)

所以,利用objc_msgSend也可以达到混编的目的

假设我们有一个OC对象NewObject继承自NSObject:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@interface NewObject : NSObject

- (void)doSomethingWith:(char *)paras;

@end

正常在OC环境中,如果我们需要调用方法的话,步骤是这样的

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
NewObject *myobj = [[NewObject alloc]init];
[myobj doSomethingWith:@"abc"];

在运行时编译时,将被转换成:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    void *myobj = objc_msgSend((id)objc_getClass("NewObject"), sel_registerName("alloc"), sel_registerName("init"));
    objc_msgSend((id)myobj, sel_registerName("doSomethingWith:"), (char *)"abc");

如果是类方法则更简单了:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
objc_msgSend((id)objc_getClass("NewObject"), sel_registerName("doThirdMethod:"), 1);

可以很清楚地看到,通过objc_getClas获取到了类,通过sel_registerName获得方法,而上面两个方法都是C函数方法,可以在C++文件中顺利调用,不过要注意先引入头文件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#import <objc/runtime.h>
#import <objc/message.h>
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
iOS runtime探究(二): 从runtime开始深入理解OC消息转发机制你要知道的runtime都在这里
你要知道的runtime都在这里 转载请注明出处 https://cloud.tencent.com/developer/user/1605429 本文主要讲解runtime相关知识,从原理到实践,由于包含内容过多分为以下五篇文章详细讲解,可自行选择需要了解的方向: 从runtime开始: 理解面向对象的类到面向过程的结构体 从runtime开始: 深入理解OC消息转发机制 从runtime开始: 理解OC的属性property 从runtime开始: 实践Category添加属性与黑魔法method sw
WWWWDotPNG
2018/04/10
1K0
iOS runtime探究(二): 从runtime开始深入理解OC消息转发机制你要知道的runtime都在这里
iOS底层原理之Runimte 运行时&方法的本质
前面探究了类里面的重要的变量,iOS 底层原理之cache分析分析了缓存方法调用流程。
CC老师
2022/01/11
4450
iOS底层原理之Runimte 运行时&方法的本质
runtime的那些事(一)——runtime基础介绍
一、 什么是runtime? 二、 runtime 版本 三、 与 runtime 的三种交互方式 四、 消息机制的基本原理与执行流程 五、 动态解析与消息转发
我只不过是出来写写代码
2019/04/22
1.7K0
runtime的那些事(一)——runtime基础介绍
[super class]和[self class]
按照我们的常规理解,super对应的应该打印Parent啊,为啥最后打印的是Son呢?
拉维
2019/11/21
7060
[super class]和[self class]
Objective-C Runtime 的一些基本使用
在上一篇文章《Objective-C Runtime详解》中我们探讨了Runtime的基本原理,这篇文章我们将总结一下Runtime的一些基本使用 目录 查询方法 给分类添加属性 更换代码的实现方法 动态添加方法 字典转属性 先创建两个类 ClassA.h #import <Foundation/Foundation.h> @interface ClassA : NSObject { // 公有变量 NSString *_publicVar1; NSString *_publ
BY
2018/05/11
1.3K0
objc_msgSend 实现分析
Runtime 有两个版本:Legacy 版本(早期版本,对应 Objective-C 1.0) 和 Modern 版本(现行版本 Objective-C 2.0)。
网罗开发
2021/07/21
9700
【IOS开发高级系列】Objective-c Runtime专题总结
http://yulingtianxia.com/blog/2014/11/05/objective-c-runtime/
江中散人_Jun
2023/10/16
4720
【IOS开发高级系列】Objective-c Runtime专题总结
Objective-C Runtime详解
Objective-C Runtime 最近在学习Runtime的知识,恰巧发现了这篇博客《Objective-C Runtime》,在此基础上,进行了些许补充说明,如有错误或其他想法,欢迎提出交流。 目录 引言 简介 与Runtime交互 RunTime术语 消息 动态方法解析 消息转发 健壮的实例变量 动态添加属性(Object-C Associated Objects) 方法调剂(Method Swizzling) 总结 引言 Objective-C的方法调用实则为“发送消息”,我们来看[dog
BY
2018/05/11
2.2K0
《Effective Objective-C》干货三部曲(一):概念篇
本书是iOS程序员入门的必读书籍,它讲述了在iOS开发中(Objective-C语言)可以遵循的规范和一些开发技巧。
用户2932962
2018/08/30
1K0
《Effective Objective-C》干货三部曲(一):概念篇
Objective-C关于id引发的一些思考 原
    Objective-C是面向对象语言,但其中又并非全部是对象。在初学这门语言时,我常常从意识上将NS开头的类型与C语言原本的那些类型分割开来,假装他们之间没有联系,只关注“类”的世界。然而类终究只是一种应用上的抽象,就像“语法糖”一样,抛开华丽的外表,内部依然是最朴素的结构体和指针。本篇博客的来由源自朋友的一个问题:在ARC环境,performSelector:withObject:方法如何传递非对象类型的数据呢?这个问题乍看起来简单,但要较较真,却也并非那么简单。下面的内容都是有这个简单的问题引出的,如果你感兴趣,在读之前可以先试着解决下上面的疑问。
珲少
2018/08/15
1.1K0
Objective-C关于id引发的一些思考
                                                                            原
Objective-C的对象模型和runtime机制「建议收藏」
对象(Object): OC中基本构造单元 (building block),用于存储和传递数据。
全栈程序员站长
2022/07/10
4060
Objective-C的对象模型和runtime机制「建议收藏」
Objective-C笔记
为什么突然要搞ObjectiveC?因为清明比较闲,两三天正好用来学习下iOS的逆向分析。 逆向的第一步当然是先从正向了解,否则给你源代码都看不懂,反编译出来的就更别提了。 因此本篇文章作为简单学习ObjC的记录,不会涉及太深入的语法特性,简而言之就是——够用就行。
evilpan
2023/02/12
1.2K0
Objective-C笔记
MessageMock : 优雅的模拟 Objective-C 方法
我们在调试代码或编写单元测试时,为了触发特定场景,往往需要通过一系列前置操作,或者直接修改源代码数据。实际上更期望有一种不需侵入源码且更快捷的方式,知名的 OCMock 正是为了解决这些问题,不过它有不支持多线程、接口怪异、重复调用、类型处理复杂等问题,笔者看了源码过后决定换一种思路,基于objc_msgSend来进行方法的“模拟”和“校验”。
波儿菜
2020/08/04
9350
MessageMock : 优雅的模拟 Objective-C 方法
动态的Objective-C——关于消息机制与运行时的探讨
    Objective-C是一种很优美的语言,至少在我使用其进行编程的过程中,是很享受他那近乎自然语言的函数命名、灵活多样的方法调用方式以及配合IDE流顺畅快编写体验。Objective-C是扩展与C面向对象的编程语言,然而其方法的调用方式又和大多面向对象语言大有不同,其采用的是消息传递、转发的方式进行方法的调用。因此在Objective-C中对象的真正行为往往是在运行时确定而非在编译时确定,所以Objective-C又被称为是一种运行时的动态语言。
珲少
2018/08/15
9020
动态的Objective-C——关于消息机制与运行时的探讨
Swift和Objective-C混编在有赞移动的实践
随着 Xcode 11、Swift 5.1 的正式发布,Swift 目前已经实现了 ABI 稳定及模块稳定,语法及实现也比以往更加成熟稳定,所以我们在微商城和零售等业务线中尝试使用 Swift 开发部分业务,并在二方库中进行混编开发,在此我们将一些混编经验分享出来。
有赞coder
2020/08/24
2.6K0
Swift和Objective-C混编在有赞移动的实践
《Objective-C高级编程》温故知新之"自动引用计数"
1、使用alloc、new、copy、mutableCopy的意味着自己生成的对象只有自己持有
Dwyane
2018/08/03
7250
《Objective-C高级编程》温故知新之"自动引用计数"
iOS Runtime应用小例子 不引入类怎么创建这个类的对象和执行类的方法
想必大家都知道Runtime 。到底Runtime是怎么创建的呢,下面是一个小demo。
星宇大前端
2019/01/15
1.1K0
iOS @property探究(二): 深入理解你要知道的@property都在这里
你要知道的@property都在这里 转载请注明出处 https://cloud.tencent.com/developer/user/1605429 上一篇文章iOS @property探究(一):基础详解介绍了@property的基本原理和使用方法,以及相关修饰符详解。 本文将会深入底层探究@property的本质。 在进入正题之前,先介绍一个clang编译器的命令 clang -rewrite-objc main.m 这个命令用于clang重写.m文件为.cpp文件。 @property深入代
WWWWDotPNG
2018/04/10
1.1K0
Objective-C Runtime 详解
Objective-C的方法调用实则为“发送消息”,我们来看[dog eat]实际会被编译器转化为
零式的天空
2022/03/28
1.4K0
Objective-C Runtime 详解
「类与对象」揭秘本质的第一步
若想了解Objective-C一些API具体实现以及一些对象真实的数据结构等,就需要将Objective-C语言转化成C/C++语言。
Jacklin
2019/11/25
4720
推荐阅读
相关推荐
iOS runtime探究(二): 从runtime开始深入理解OC消息转发机制你要知道的runtime都在这里
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验