Я работаю над проектом, который реализует библиотеку C, используя Swift.До сих пор мне удавалось управлять тем, как получить String из строк C и некоторых других.
Теперь я сталкиваюсь с проблемой при работе с обратным вызовом C, который возвращает переменные OUT типа char **.Код swift должен перераспределить память и изменить значение.Эти переменные используются для типа String.
Заголовок для функции C:
DllExport void STDCALL DvProviderGetProtocolInfo(THandle aProvider, CallbackGetProtocolInfo aCallback, void* aPtr);
И заголовок для обратного вызова C:
typedef int32_t (STDCALL *CallbackGetProtocolInfo)(void* aPtr, IDvInvocationC* aInvocation, void* aInvocationPtr, char** aSource, char** aSink);
Inswift Я вызываю функцию следующим образом:
DvProviderGetProtocolInfo(prvHandleId, { (pointer, aInvocation, aInvocationPtr, aSource, aSink) -> Int32 in
let senderClass:SenderClass = bridgeToTypeUnretained(ptr: pointer!)
senderClass.writeCStringValue(from: aSource, withValue: senderClass.sourceProtocolInfoArray)
senderClass.writeCStringValue(from: aSink, withValue: senderClass.sinkProtocolInfoArray)
return 0
}, bridgeToPointerRetained(obj: self))
Используются следующие функции:
public func writeCStringValue(from pointer:UnsafeMutablePointer<UnsafeMutablePointer<Int8>?>?, withValue value:String){
pointer!.pointee = UnsafeMutablePointer<Int8>.allocate(capacity:value.utf8.count)
strcpy(pointer!.pointee, value)
}
И объявлены в другом файле 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())
}
Пока чтодля небольших значений функция writeCStringValue работает нормально, но когда я пытаюсь отправить длинную строку, например:
let aTest = "http-get:*:audio/m4a:*,http-get:*:audio/x-m4a:*,http-get:*:audio/aiff:*,http-get:*:audio/x-aiff:*,http-get:*:audio/mpeg:DLNA.ORG_PN=MP3,http-get:*:audio/mp4:*,http-get:*:audio/wav:*,http-get:*:audio/wave:*,http-get:*:audio/x-wav:*,http-get:*:video/mpeg:*,http-get:*:video/mp4:*,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_TN,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_SM,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_MED,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_LRG,http-get:*:image/png:DLNA.ORG_PN=PNG_TN,http-get:*:image/png:DLNA.ORG_PN=PNG_LRG"
, я получаю EXC_BAD_ACCESS в конце функции writeCStringValue.
Если я включу кодв функции writeCStringValue внутри функции обратного вызова не происходит сбоя.
В идеале я хотел бы использовать функцию writeCStringValue.
Правильно ли я изменяю значения char **?
Спасибо