目录
上一个教程讲了在xcode中,用c来调用c++代码,是为了这篇教程做铺垫,因为swift调用c++的方法1,就是用swift调用c代码
下面2篇文章是专门针对extern “C” 和 ifdef __cplusplus的讲解:
extern “C“的作用:c语言调用c++代码中普通函数和类的方法教程(符xcode编译器演示demo)
extern “C” 和 #ifdef __cplusplus 作用
整体思路:因为swift不能直接调用c++,但是可以调用c,所以我们让swift调用c,再用c调用c++.强烈建议查看上面的文章,里面有c调用c++的原理说明.
#传送门2 这篇文章讲了如何用swift调用c: swift和c语言互相调用教程
swift调用 C++ 方法
假设你已经查看了我上面2教程,那么用上面的旧知识组合起来,先给c++的类制作对外的全局方法,用来创建类 和 调用方法:
.hpp文件就是 c++的.h文件,只不过用vc++编译器就是.h文件,用xcode编译器就是.hpp文件
这个头文件里面声明了 类和 里面的方法,这个 .hpp是不能让.swift包含的,否则一定会报错,因为swift不识别cpp语法
//
// CPerson.hpp
// swiftCppDemo
//
// Created by 谭迪文 on 2021/6/25.
//
#ifndef CPerson_hpp
#define CPerson_hpp
#include <stdio.h>
#include <iostream>
#endif /* CPerson_hpp */
using namespace::std;
class CPerson
{
string name;
int age;
string className;
public:
CPerson();
~CPerson();
CPerson(string name,int age,string className);
void printInfo();
const char * getName();
private:
};
.cpp文件,里面不但定义了 .hpp里面声明过的对象方法,还多出来 2个全局的 函数指针pFn1,pFn2 和一个 全局的方法CRunSwift,这3个东西是全局的,在cpp文件里是定义,为了让swift能识别,需要加extern "C"来声明,为了方便,单独创建一个.h文件命名为CBridging.h 文件
//
// CPerson.cpp
// swiftCppDemo
//
// Created by 谭迪文 on 2021/6/25.
//
#include "CPerson.hpp"
#include "CBridging.h"
void* create();
void* createBy(const char* name,int age,const char * className);
CPerson::CPerson() {
}
CPerson::~CPerson() {
}
CPerson::CPerson(string name,int age,string className){
this->name = name;
this->age = age;
this->className = className;
}
void CPerson ::printInfo(){
cout<< "name=" <<this->name << "age = "<<this->age << "className = " <<this->className <<endl;
}
const char * CPerson ::getName(){
return this->name.data();
}
//下面3个全局方法,让c语言可以调用c++的类
void* create() {
return new CPerson();
}
void* createBy(const char* name,int age,const char * className){
return new CPerson(name,age,className);
}
void printInfo(void* p){
//因为c语言没有类,所以只能传入空类型的指针,然后强转成对象指针,再执行
((CPerson*)p)->printInfo();
}
const char* getName(void* p){
return ((CPerson*)p)->getName();
}
void(^ pFn1)(int)= NULL;//定义函数指针
void (^ pFn2)(int) = NULL;//定义函数指针
void CRunSwift(){
pFn1(10);
pFn2(5);
}
CBridging.h这个文件里面是extern “C” 的内容,关于extern “C的说明”,请查看 这篇文章:extern “C“的作用:c语言调用c++代码中普通函数和类的方法教程(符xcode编译器演示demo)
注意,这个CBridging.h文件要被CPerson.cpp文件包含,同时还要给swift的桥接文件包含.
swift的桥接文件制作,当你新建oc文件,或者c文件的时候就会提示是否生成桥接文件,或者像下面这样手动创建:
建立桥接文件
这个在建立c语言文件的时候回自动提示是否生成 桥接 文件,直接选是,如果点击了取消,可以手动创建
新建一个.h文件,一般系统自动建立的桥接文件是 项目名+ -Bridging-Header.h,我们也模仿系统起名,SwiftCDemo-Bridging-Header.h
然后build setting -> 搜索 bri, 找到0bjective-C Bridging Header ,然后输入文件名SwiftCDemo-Bridging-Header.h
如下图
桥接文件里面的内容就一句话:
#import "CBridging.h"
swift中的调用
里面调用c++的方法可以直接调用,c++调用swift方法,是在c++里调用函数指针,然后在swift里面把方法名赋值给函数指针,然后在c++中调用函数指针指向的地址
//
// ViewController.swift
// swiftCppDemo
//
// Created by 谭迪文 on 2021/6/25.
//
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let p1 = create()
let p2 = createBy("zhangsan", 18, "大三2班")
printInfo(p2)
let className = getName(p2)
print("className=",className!)
pFn1 = swiftFn(result:)
pFn2 = swiftFn2(result: )
CRunSwift()//调用c++里面的方法,让c++通过函数指针pFn1,pFn2反过来调用swift的两个方法
}
func swiftFn(result:Int32)->Void{
print("swift中的方法swiftFn执行,result=",result)
}
func swiftFn2(result:Int32)->Void{
print("swift中的方法swiftFn2执行,result=",result)
}
}
demo点我下载
demo是通过在cpp文件中建立对外c函数被swift调用c++的