目標
作爲一個以跨平臺爲目標的三方庫,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