как извлечь данные из void UnsafePointer в Swift?

У меня есть следующий код в Objective-C (который использует структуру Audio Toolbox), который я пытаюсь преобразовать в Swift:

MusicTimeStamp timeStamp;
MusicEventType eventType;
const void *eventData;
UInt32 eventDataSize;

//MusicEventIteratorGetEventInfo is declared in Audio Toolbox framework as this:
//OSStatus MusicEventIteratorGetEventInfo ( MusicEventIterator inIterator, MusicTimeStamp *outTimeStamp, MusicEventType *outEventType, const void **outEventData, UInt32 *outEventDataSize );

MusicEventIteratorGetEventInfo(anIterator, &timeStamp, &eventType, &eventData, &eventDataSize);

switch (eventType){
    case kMusicEventType_MIDINoteMessage:
        //extract info from eventData assuming it's a MIDINoteMessage.
        UInt8 channel = ((MIDINoteMessage *) eventData)->channel
        UInt8 note = ((MIDINoteMessage *) eventData)->note
        UInt8 velocity = ((MIDINoteMessage *) eventData)->velocity
        Float32 duration = ((MIDINoteMessage *) eventData)->duration

    case kMusicEventType_MIDIChannelMessage:
        //extract info from eventData assuming it's a MIDIChannelMessage.

    //case ..., etc.
}

Переписывая его на Swift, я не могу понять, как получить данные из части «const void *eventData», несмотря на чтение документации Apple по небезопасным указателям (ни один из их примеров, похоже, не относится к извлечению данных из небезопасный указатель таким образом). Это то, что у меня есть до сих пор, но я потерялся с точки зрения того, каким должен быть оператор switch:

var timeStamp: MusicTimeStamp = 0
var eventType: MusicEventType = 0
var eventData: UnsafeMutablePointer<UnsafePointer<Void>> = nil
var eventDataSize: UInt32 = 0

MusicEventIteratorGetEventInfo(iterator, &timeStamp, &eventType, eventData, &eventDataSize)

//what would simplest equivalent switch statement be?

Любая помощь будет оценена по достоинству - спасибо.


person chris.bennett    schedule 24.09.2014    source источник
comment
этот пост посвящен небезопасным указателям stackoverflow.com/questions/ 24838106/   -  person chris    schedule 24.09.2014
comment
для чего-то столь фундаментального для основных библиотек Apple, неужели нет более простого способа? честно говоря, я даже не уверен, что смогу понять, как применить этот пост к моему примеру, хотя я уверен, что он полезен для большинства...   -  person chris.bennett    schedule 25.09.2014
comment
Я бы использовал для этого Objective-C и вызывал высокоуровневые объекты/методы из Swift. Это не должно быть таким сложным.   -  person Matteo Pacini    schedule 30.10.2014


Ответы (1)


Пока вы знаете, какие данные заперты в этом небезопасном указателе, вы всегда можете использовать различные конструкторы каждого варианта для приведения типов между указателями. Ваш пример тривиален для перевода, если вы помните об этом:

import AudioToolbox

var timeStamp : MusicTimeStamp = 0
var eventType : MusicEventType = 0
var eventData : UnsafePointer<Void> = nil
var eventDataSize : UInt32 = 0;

MusicEventIteratorGetEventInfo(anIterator, &timeStamp, &eventType, &eventData, &eventDataSize);

switch (eventType){
    case kMusicEventType_MIDINoteMessage:
        let data = UnsafePointer<MIDINoteMessage>(eventData)
        let channel = data.memory.channel
        let note = data.memory.note
        let velocity = data.memory.velocity
        let duration = data.memory.duration

    case kMusicEventType_MIDIChannelMessage:
        //extract info from eventData assuming it's a MIDIChannelMessage.

        //case ..., etc.
}
person CodaFi    schedule 03.11.2014
comment
Есть несколько обновлений для Swift 3, но как только вы 1> var eventData: UnsafeRawPointer? = nil and2› let data = UnsafePointer‹MIDINoteMessage›(eventData?.assignMemoryBound(to: MIDINoteMessage.self)) остальное должно быть очевидно - person narco; 10.01.2017