Swift UnsafeMutablePointer <Unmanaged <CFSsortingng>?> Allocation et printing

Je suis nouveau à swift et j'ai quelques difficultés à gérer les pointeurs de CFSsortingng non géré (ou NSSsortingng). Je travaille sur un projet CoreMIDI qui implique l'utilisation de UnsafeMutablePointer?> Comme vous pouvez le voir dans cette fonction:

func MIDIObjectGetSsortingngProperty(_ obj: MIDIObjectRef, _ propertyID: CFSsortingng!, _ str: UnsafeMutablePointer<Unmanaged<CFSsortingng>?>) -> OSStatus 

Mon problème est que je veux allouer un tampon pour recevoir le contenu de la propriété (_str) puis appeler la fonction ci-dessus, et enfin imprimer le contenu de la console en utilisant println.

En ce moment j'ai écrit ceci:

 // Get the first midi source (I know it exists) var midiEndPoint : Unmanaged<MIDIEndpointRef> = MIDIGetSource(0) //C reate a "constant" of 256 let buf = NSMutableData(capacity: 256) // Allocate a ssortingng buffer of 256 characters (I'm not even sure this does what I want) var name = UnsafeMutablePointer<Unmanaged<CFSsortingng>?>(buf!.bytes) // Call the function to fill the ssortingng buffer with the display name of the midi device var err : OSStatus = MIDIObjectGetSsortingngProperty(&midiEndPoint,kMIDIPropertyDisplayName,name) // Print the ssortingng ... here no sursockets I don't know what to write to print the content of the pointer, so it prints the address for the moment println(name) 

Je n'ai trouvé aucun exemple de code pour utiliser les fonctions CoreMIDI sur la bibliothèque Apple Developper pas sur Internet. Je suis vraiment confus parce que je viens de cpp et les choses sont très différentes dans Swift.

MODIFIER :

Après les réponses de Rintaro et Martin j'ai toujours un problème, tous mes tests sont effectués sur iOS 8.1 et si je copy le code que vous m'avez apporté, le compilateur me dit que je ne peux pas écrire:

 let err = MIDIObjectGetSsortingngProperty(midiEndPoint, kMIDIPropertyDisplayName, &property) 

Les résultats dans 'Unmanaged' ne sont pas convertibles en 'MIDIObjectRef'. J'ai donc ajouté un "&" car MIDIObjectRef est un UnsafeMutablePointer <void>.

 let midiEndPoint = MIDIGetSource(0) var property : Unmanaged<CFSsortingng>? let err = MIDIObjectGetSsortingngProperty(&midiEndPoint, kMIDIPropertyDisplayName, &property) 

Maintenant: 'Unmanaged <MIDIEndpoint>' n'est pas convertible en '@lvalue inout $ T2'. Enfin j'ai dû changer le premier laissé à var, sans comprendre pourquoi?!?

 var midiEndPoint = MIDIGetSource(0) var property : Unmanaged<CFSsortingng>? let err = MIDIObjectGetSsortingngProperty(&midiEndPoint, kMIDIPropertyDisplayName, &property) 

Le code se comstack et s'exécute, mais MIDIObjectGetSsortingngProperty returnne OSStatus err -50 qui correspond à IOW ou à MacErros.h:

 paramErr = -50, /*error in user parameter list*/ 

Il semble donc que les parameters ne sont pas ceux que MIDIObjectGetSsortingngProperty attend.

La source "0" existe sur mon iPad car MIDIGetNumberOfSources () renvoie 1. Voici le code complet:

 var numDestinations: ItemCount = MIDIGetNumberOfDestinations() println("MIDI Destinations : " + Ssortingng(numDestinations)) for var i : ItemCount = 0 ; i < numDestinations; ++i{ var midiEndPoint = MIDIGetDestination(i) var property : Unmanaged<CFSsortingng>? let err = MIDIObjectGetSsortingngProperty(&midiEndPoint, kMIDIPropertyDisplayName, &property) if err == noErr { let displayName = property!.takeRetainedValue() as Ssortingng println(displayName) }else{ println("error : "+Ssortingng(err)) } } 

Affiche:

 MIDI Destinations : 1 error : -50 

Je ne comprends vraiment rien …

METTRE À JOUR :

Finalement Martin a trouvé la solution, il semble qu'il y ait deux définitions différentes de MIDIObjectRef dans les architectures 32 et 64bits. Comme je cours le code sur un vieux iPad 2 mon code a essayé de comstackr en mode 32bits où la valeur de return de MIDIGetSource (i) n'est pas convertible en MIDIObjectRef. La solution est de "jeter en toute security" le sharepoint terminaison midi sur les architectures 32 bits:

 #if arch(arm64) || arch(x86_64) let midiEndPoint = MIDIGetDestination(i) #else let midiEndPoint = unsafeBitCast(MIDIGetDestination(i), MIDIObjectRef.self) #endif 

… Ou pour acheter un nouvel appareil 64 bits …

Merci pour l'aide précieuse

Je n'ai aucune expérience avec CoreMIDI et je n'ai pas pu le tester, mais voici comment cela devrait fonctionner:

 let midiEndPoint = MIDIGetSource(0) var property : Unmanaged<CFSsortingng>? let err = MIDIObjectGetSsortingngProperty(midiEndPoint, kMIDIPropertyDisplayName, &property) if err == noErr { let displayName = property!.takeRetainedValue() as Ssortingng println(displayName) } 

Comme @rintaro l'a remarqué correctement, takeRetainedValue() est le bon choix car il est de la responsabilité des appelants de libérer la string. Ceci est différent des règles habituelles de memory management de base de base, mais documenté dans la reference des services MIDI :

REMARQUE

Lorsque vous passez un object Foundation Core à une fonction MIDI, la fonction MIDI ne consum jamais de reference à l'object. L'appelant conserve toujours une reference qu'il est responsable de libérer en appelant la fonction CFRelease.

Lors de la réception d'un object Foundation Core en tant que valeur de return d'une fonction MIDI, l'appelant reçoit toujours une nouvelle reference à l'object et est responsable de sa libération.

Voir "Objets non gérés" dans "Utilisation des types de données Cocoa" pour plus d'informations.

UPDATE: Le code ci-dessus ne fonctionne que lors de la compilation en mode 64 bits. En mode 32 bits, MIDIObjectRef et MIDIEndpointRef sont définis comme différents types de pointeurs. Ce n'est pas un problème dans (Objective-) C, mais Swift n'autorise pas une conversion directe, un "cast non sécurisé" est nécessaire ici:

 let numSrcs = MIDIGetNumberOfSources() println("number of MIDI sources: \(numSrcs)") for srcIndex in 0 ..< numSrcs { #if arch(arm64) || arch(x86_64) let midiEndPoint = MIDIGetSource(srcIndex) #else let midiEndPoint = unsafeBitCast(MIDIGetSource(srcIndex), MIDIObjectRef.self) #endif var property : Unmanaged<CFSsortingng>? let err = MIDIObjectGetSsortingngProperty(midiEndPoint, kMIDIPropertyDisplayName, &property) if err == noErr { let displayName = property!.takeRetainedValue() as Ssortingng println("\(srcIndex): \(displayName)") } else { println("\(srcIndex): error \(err)") } }