苹果推出Swift后,很快就受到程序猿的青睐,快速、安全、简洁的开发已经是一个大趋势了。如果在加上C和C++真的是天衣无缝了,完美结合。对于Swift调用C和C++,通常需要OC做桥接(oc调用c和c++),性能得不到优化。我们今天直接用Swift调用C使性能得到全面的提升。苹果号称和C一样快的Swift的demo我们来粒子。

测试环境:

Xcode版本:11.0 Swift版本:5.0

Swift直接调用C

我们直接进入主题,Swift调用C。先创建一个工程SwiftAndC,然后创建一个C文件,命名为CTest,.h文件创建以下函数

1
2
3
4
5
6
7
8
9
10
11
#ifndef CTest_h
#define CTest_h

#include <stdio.h>

void(^ __nonnull swiftFuncIMP)(int) = NULL;

void printHellow(void);
int getRandomInt(void);
void runSwiftFun(void);
#endif /* CTest_h */

在.c文件里实现该函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "CTest.h"
#include <stdlib.h>
void printHellow(void){
printf("hellow world,I am is C language\n");
}

int getRandomInt(void){
return rand();
}
/**该方法用于Swift调用,用于测试函数中调用Swift方法是否成功*/
void runSwiftFun(void){
/**实现中,调用Swift函数*/
swiftFuncIMP(10);
}

我们定义两个c函数(c不是很厉害只能这么简单,会使用就好)。我们现在用Swift调用。

我们定义一个头文件,也就是对外(swift)的接口。我们创建一个.h文件,命名为CBridgie.h。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#ifndef CBridge_h
#define CBridge_h
typedef void* CDogModel;
#ifdef __cplusplus
extern "C" {
#endif

/**C方法
*/
void printHellow(void);
int getRandomInt(void);

/**C++方法
*/
CDogModel create();
CDogModel createBy(const char* name,int age);
void printDogInfo(CDogModel model);
const char* getDogName(CDogModel model);
void destoryModel(CDogModel model);

/**
C方法
用Swift调用此方法
测试C调用Swift方法是否成功
ps:如果不调用此方法,如何测试C调用Swift方法成功?
*/
void runSwiftFun(void);


#ifdef __cplusplus
}
#endif
#endif /* CBridge_h */

对于上边的定义如果不是很明白,可以自己在网上查查,有很多讲解,我在这里就不多说啦。在创建的时候会有提示是否创建桥接文件,记得点击是,如果点击了否,那么就要自己创建了,怎么创建呢。推荐一篇文章。

我们需要在桥接文件中导入CBridge.h。然后我们在默认的ViewController.swift里运行。

1
2
3
4
5
6
7
8
9
private func swiftUseC(){
print("--------------------\n")
print("Swift使用C")
printHellow()
let t = getRandomInt()
print(t)
print("--------------------\n")
}

到此,我们已经成功的调用的C语言。对于c++呢我们也是这个方法。

Swift调用C++

swift要调用c++和c是一样的。我们先创建一个c++文件,命名为DogModel。
在.hpp里声明一个类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#ifndef DogModel_hpp
#define DogModel_hpp

#include <stdio.h>
#include <iostream>
using namespace std;
class DogModel{
string name;
int age;
public:
DogModel();
DogModel(const char * name, int age);
~DogModel();
void printDogInfo();
const char* getDogName();
};

#endif /* DogModel_hpp */

在.cpp里实现这个类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include "DogModel.hpp"
#include "CBridge.h"

DogModel::DogModel(){
this->name = "旺财";
this->age = 20;
}

DogModel::DogModel(const char * name,int age){
this->name = name;
this->age = age;
}

void DogModel::printDogInfo(){
cout << "i am is " << name << ",my age is "<< age;
cout << "\n";
}
const char* DogModel::getDogName() {
return name.data();
}

DogModel::~DogModel(){
cout << "\n释放资源\n";
}


// MARK: - 实现接口函数

CDogModel create() {
return new DogModel();
}
CDogModel createBy(const char* name,int age){
return new DogModel(name,age);
}
void printDogInfo(CDogModel model) {
DogModel *p = (DogModel*)model;
p->printDogInfo();
}
const char* getDogName(CDogModel model){
DogModel *p = (DogModel*)model;
return p->getDogName();
}
void destoryModel(CDogModel model){
DogModel *p = (DogModel*)model;
delete p;
}

我们在CBridge.h中加上c++接口:

1
2
3
4
5
6
7
/**C++方法
*/
CDogModel create();
CDogModel createBy(const char* name,int age);
void printDogInfo(CDogModel model);
const char* getDogName(CDogModel model);
void destoryModel(CDogModel model);

记得加上声明:

typedef void* CDogModel;

我们需要在.cpp文件里实现这些函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// MARK: - 实现接口函数

CDogModel create() {
return new DogModel();
}
CDogModel createBy(const char* name,int age){
return new DogModel(name,age);
}
void printDogInfo(CDogModel model) {
DogModel *p = (DogModel*)model;
p->printDogInfo();
}
const char* getDogName(CDogModel model){
DogModel *p = (DogModel*)model;
return p->getDogName();
}
void destoryModel(CDogModel model){
DogModel *p = (DogModel*)model;
delete p;
}

在ViewController.swift调用

1
2
3
4
5
6
7
8
9
10
11
12
private func swiftUseCP(){
print("--------------------\n")
print("Swift使用C++")
let person = createBy("peter", 2);
printDogInfo(person);
let cName = getDogName(person);
let name = String(cString: cName!);
print("fetch name is:\(name)");

destoryModel(person);
print("--------------------\n")
}

C调用Swift

swift调用C,那么C也能调用Swift。我们来看看是怎么调用的。

在桥接文件里声明一个回调函数:

extern void(^ __nonnull swiftFuncIMP)(int);

在CTest.h文件里初始化

void(^ __nonnull swiftFuncIMP)(int) = NULL;

在swift里声明一个函数,并赋值给这个回调函数。

1
2
3
func C_UserSwiftFun(a:Int32) -> Void {
print("收到一个c函数的Int值->\(a)");
}

最后附上demo地址

欢迎指正。