Swift & Objective-C & C++之间的混编

2020/2/11 posted in  iOS

①Objective-C 调用 C++

OC本身可以直接调用C的代码 比如直接可以调用printf方法。
但是OC中的.m直接编译C++的代码就会出现编译错误
需要把OC.m改成OC.mm之后(objective-c变成了objective-c++)引入iostream(#include<iostream>)就可以直接编译了。
这可以在.mm文件当中直接使用c++的代码。
也可以另外新建一个c++的文件,并且创建.h文件。

********CPPHello.hpp声明文件********
#ifndef CPPHello_hpp
#define CPPHello_hpp

#include <stdio.h>
class CPPHello{
    
public:
    static void sayHello();
};

#endif /* CPPHello_hpp */
********CPPHello.cpp实现文件********
#include "CPPHello.hpp"

void CPPHello::sayHello(){
    
    printf("hello world");
    
}

注意:oc调用c++必须要把.m改成.mm,要不然会报错。

②C++ 调用 Objective-C

新建cocoaTouch中的类,语言选择Objective-C,比如objcHello.hobjcHello.m然后在刚才的c++文件(CPPHello.cpp)中import objcHello.h就会出现编译错误。
所以c++语言不能直接import OC的头文件要对头文件进行修改,把头文件所有内容删除替换成c++能够识别的代码比如c或者c++的代码。

//objcHello.h
void objcSayHello();

另外objcHello.m文件要修改成objcHello.mm文件,然后#import <Foundation/Foundation.h>之后就可以在objcHello.mm文件调用oc的代码了。
并且可以在objcHello.mm文件中写oc的类了,比如如下代码。

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

@interface ObjcHello:NSObject

-(void)sayHello;

@end

@implementation ObjcHello

-(void)sayHello{
    
    NSLog(@"hello objc");
}
@end


void objcSayHello(){
    
//  NSLog(@"hello Objc");
    ObjcHello * h = [ObjcHello new];
    [h sayHello];
}

然后修改完之后引入比如#include "ObjcHello.h"就可以在里面对.h文件的方法进行调用了。

#include "CPPHello.hpp"
#include "ObjcHello.h"
void CPPHello::sayHello(){
    
//   printf("hello world");
    objcSayHello();
    
}

③Swift调用C

新建CHello.h文件,然后创建头文件,然后选择创建桥接文件。
在这个桥接文件中#import其他公开头文件用来暴露给swift文件。

1.在.h文件中声明一个方法

CHello.h
#ifndef CHello_h
#define CHello_h

#include <stdio.h>
void sayHello();
#endif /* CHello_h */

2.在.c文件中实现一个方法

Chello.c 
#include "CHello.h"

void sayHello(){
    
    printf("hello c");
    
}

3.在桥接文件中引入CHello.h

//  Use this file to import your target's public headers that you would like to expose to Swift.
//

#import "CHello.h"

4.在swift当中直接调用sayHello()方法

④Swift & Objective-C & C++混编

新建OC的类比如OCHello.h和OCHello.m

#import <Foundation/Foundation.h>

@interface OCHello : NSObject
-(void)hello;
@end
#import "OCHello.h"

@implementation OCHello
-(void)hello{
    
    NSLog(@"oc sayHello");
}
@end

然后在桥接文件中引入OCHello.h
在swift当中就可以直接调用,代码如下所示

import UIKit
class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        var h = OCHello();
        h.hello()

    }
}

如果想要swift调用c++的话可以把OCHello.m改成OCHello.mm
在.mm文件中写c++的代码如下所示

#include <iostream>
#import "OCHello.h"

@implementation OCHello
-(void)hello{
    
//    NSLog(@"oc sayHello");
    std::cout<<"hello cpp\n";
}
@end

swift当中的代码不做任何变化,这样就做到了三种语言的混编。

提示

.mm文件当中可以写oc,c,c++的代码
oc可以完全兼容c语言的代码
swift不可以直接执行c语言的代码,要做一些声明比如上面的调用实现。
swift不可以执行c++的代码,要用oc做中间层,一般要避免。