目标
作为一个以跨平台为目标的三方库,iOS端是必然要支持的。
从技术语言上来说,可以使用如下两个方案:
- OC + C++
- Swift + C++
经过一番考虑后,放弃了第一种而采用了第二种。原因是OC的语法太丑了。
Swift和C++是无法直接进行通信的,好在Swift提供了一种桥"Birdge"的方案,能让Swift和C++互调代码。
由此为基础,我们就可以实现在iOS平台上,基于一份C++代码的多端支持了。
设计
虽然Swift和C++能通过"Birdge"的能力进行双向通信,但是有些坑还是不得不踩的。 由于我本人并非iOS开发。该方案可能并非最优解,提出来以供参考。
从技术能力上来说,Birdge能力是提供一组全局静态的方法以供Swift调用,如果Swift的使用方也同样是静态方法,那么直接通信并无任何问题。
如果从面向对象的角度来说,我们都希望功能和方法封装成为一个类,并使用类的实例来调用相关方法,那么此时就会碰到困难,因为我们无法在对象中与静态C++方法进行有效的对象级通信。
为了解决这个问题,我们引入Holder
这样一个角色,它持有我们的对象类引用,并且在调用C++方法时,我们都将该Holder
传入到C++层中,以便C++层可以正确的回调到正确的对象引用。
实现
方案的实的重点也在于该如何实现Swift对象到Native对象之间的通信,以及让Swift对象持有Native对象。
- 定义一个
Int64
的变量,用于存储Native产生的对象指针,方便在调用Swift对象的方法时,可以找到已经实例化过的Native对象。 - 定义一个
Holder
类,并定义一个变量,用于持有Swift对象本身,之所以这么做可以方便索引到已经实例化过的Swift对象。 - 定义静态通信的方法,并在通信的时候传递Swift对象的引用,方便对对象调用方法。
定义Native对象的持有指针:
// Native pointer to DSM object
private var dsmNativePointer: Int64 = 0
定义Holder
类,持有Swift对象:
private class DsmHolder {
fileprivate var dsm: Dsm? = nil
}
定义静态通信方法:
bridge:
typedef void (*OnEventFromNative)(_DsmHolder *_Nonnull dsmHolder, int what, const char *_Nullable json);
Swift:
DSM_onEventFromNative = { (dsmSelf: UnsafeMutableRawPointer, what: Int32, json: UnsafePointer<Int8>?) -> Void in
}
引用
- https://github.com/biezhihua/libdsm