Я работаю над проектом Swift, в котором используется библиотека C, обернутая в C ++.
Библиотека предлагает вам возможность получать / устанавливать переменные синхронно и асинхронно.
Библиотека как методы обратного вызова, которая уведомляет, когда и даже произошло.
У меня есть эта функция в swift:
/*** Convert const void* To Any T ***/
func bridgeToTypeRetained<T : AnyObject>(ptr : UnsafeMutableRawPointer) -> T {
return Unmanaged<T>.fromOpaque(ptr).takeRetainedValue()
}
func bridgeToTypeUnretained<T : AnyObject>(ptr : UnsafeRawPointer) -> T {
return Unmanaged<T>.fromOpaque(ptr).takeUnretainedValue()
}
и
/*** Convert const void* To Any T ***/
func bridgeToPointerRetained<T : AnyObject>(obj : T) -> UnsafeMutableRawPointer {
return UnsafeMutableRawPointer(Unmanaged.passRetained(obj).toOpaque())
}
func bridgeToPointerUnretained<T : AnyObject>(obj : T) -> UnsafeMutableRawPointer {
return UnsafeMutableRawPointer(Unmanaged.passUnretained(obj).toOpaque())
}
Для реализации обратных вызовов из библиотеки, в библиотеке у меня есть следующие определения:
DllExport void STDCALL CpProxyAvOpenhomeOrgInfo1SetPropertyTrackCountChanged(THandle aHandle, OhNetCallback aCallback, void* aPtr);
typedef void (STDCALL *OhNetCallback)(void* aPtr);
Тогда в swift я использую следующий код:
CpProxyAvOpenhomeOrgInfo1SetPropertyTrackCountChanged(myHandle, { (pointer) in
if pointer != nil{
let myClass:MyClass = bridgeToTypeRetained(ptr: pointer!)
myClass.aValu = 0 //CRASH BAD ACCESS
let myClass:MyClass = bridgeToTypeUnretained(ptr: pointer!)
myClass.aValu = 0 //NO CRASH
}
}, bridgeToPointerRetained(obj: self))
А для реализации асинхронного действия в Библиотеке у меня есть следующие определения:
DllExport void STDCALL CpProxyAvOpenhomeOrgInfo1BeginCounters(THandle aHandle, OhNetCallbackAsync aCallback, void* aPtr);
typedef void (STDCALL *OhNetCallbackAsync)(void* aPtr, OhNetHandleAsync aAsync);
Тогда быстро я использую следующий код
let classCallback = ClassCallback()
classCallback.classObject = self
CpProxyAvOpenhomeOrgInfo1BeginCounters(prxHandleId, { (pointer, ohNetAsync) in
if pointer != nil && ohNetAsync != nil{
let classCallback : ClassCallback = bridgeToTypeRetained(ptr: pointer!)
classCallback.classObject.aValue = 1 //NO CRASH
}
}, bridgeToPointerRetained(obj: classCallback))
Итак, мои вопросы будут:
- Когда мне нужно использовать takeRetainedValue () или takeUnretainedValue () в соответствии с информацией, которую я могу получить из библиотеки C ++?
Спасибо.