swift中调用c/c++

做过OC与swift混编的都知道,若实现swift调用OC的方法或OC调用swift方法,需要建立一个桥接文件,例如命名:MyBridging.h,在Build Settings中添加配置Swift Compiler - General中的Objective-C Bridging Header:MyBridging.h

我们先来回忆一下这块儿的知识,首先我们先来建立一个OC的类

@interface TestOC : NSObject

- (NSInteger)oc_addA:(NSInteger)a b:(NSInteger)b NS_SWIFT_NAME(oc_add(a:b:)); // 这里可以指定swift在调用该方法时的方法名
- (NSInteger)oc_call_swift_addWithA:(NSInteger)a b:(NSInteger)b;

@end

#import "TestOC.h"
#import "TestC-Swift.h" // oc调用swift时,需要导入这个头文件,这个是xcode自动生成的,命名规则为:“工程名称-Swift.h”,这里包含了全部可以被OC调用的swift类

@implementation TestOC

- (NSInteger)oc_addA:(NSInteger)a b:(NSInteger)b{
    return a + b;
}

- (NSInteger)oc_call_swift_addWithA:(NSInteger)a b:(NSInteger)b{
    // oc调用swift方法
    SwiftObj *swift = [[SwiftObj alloc] init];
    return [swift swiftAddWithA:a b:b];
}

@end

工程名称可以在Build Settings中修改:

然后在桥接文件中添加OC类的头文件,在MyBridging.h中导入OC类

#import "TestOC.h"

然后就可以在swift中调用OC的类了,如下:

func test() {
    let oc = TestOC() // 初始化OC的类
    print("20+20=\(oc.oc_add(a: 20, b: 20))") // 调用OC的方法
    print("30+30=\(oc.oc_call_swift_add(withA: 30, b: 30))")
}

OC调用swift类,必须满足类对象为class类型,并且该类继承自NSObject,如下:

class SwiftObj: NSObject {
    
    @objc(swiftAddWithA:b:) // 重命名OC调用时的方法名
    func swift_add(a: Int, b: Int) -> Int {
        a + b
    }
}

OC调用swift类,前提需要调入xcode自动转换的头文件,前面已经讲了

// oc调用swift方法
SwiftObj *swift = [[SwiftObj alloc] init];
return [swift swiftAddWithA:a b:b];

 

好了,说完了OC与swift的混编,接下来言归正传,回到我们今天的主题,swift调用C/C++函数

有两种方式实现,第一种同样利用桥接文件(Objective-C Bridging Header),第二种则是利用swift的标注(@_silgen_name

先说第一种:

我们先来建立一个C文件,test.h、test.c(实际上test.h头文件可以不需要

#ifndef test_h
#define test_h

#include <stdio.h>

int c_add(int a, int b);

#endif /* test_h */



#include "test.h"


int c_add(int a, int b){
    return a + b;
}

然后在桥接文件中添加如下代码,用于导出C函数

#ifdef __cplusplus
extern "C" { // 这是为了兼容c++
#endif

int c_add(int a, int b); // 相当于导出c的函数

#ifdef __cplusplus
}
#endif
func test() {
    print("10+20=\(c_add(10, 20))") // swift调用c函数
}

 

接下来说说第二个方法,该方法不需要创建桥接文件,而是利用swift提供的标注@_silgen_name

@_silgen_name("c_add") // 将c函数c_add的imp作为被标注的方法的imp
func swift_add(a: Int, b: Int) -> Int // 这个swift方法的imp实际上被指向了c函数c_add

然后在swift中调用如下:

print("1+2=\(swift_add(a: 1, b: 2))")

很明显第二个方法更加简单,不需要引入桥接文件。

 

posted @ 2021-08-18 17:56  zbblogs  阅读(1490)  评论(0编辑  收藏  举报