私はswiftが初めてで、管理されていないCFString(またはNSString)のポインターを処理するのにいくつかの困難があります。この関数でわかるように、UnsafeMutablePointer?> の使用を意味する CoreMIDI プロジェクトに取り組んでいます。
func MIDIObjectGetStringProperty(_ obj: MIDIObjectRef,
_ propertyID: CFString!,
_ str: UnsafeMutablePointer<Unmanaged<CFString>?>) -> OSStatus
私の問題は、プロパティ (_str) の内容を受け取るためのバッファーを割り当て、上記の関数を呼び出し、最後に println を使用してコンソールに内容を出力することです。
現時点で私はこれを書いた:
// 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 string buffer of 256 characters (I'm not even sure this does what I want)
var name = UnsafeMutablePointer<Unmanaged<CFString>?>(buf!.bytes)
// Call the function to fill the string buffer with the display name of the midi device
var err : OSStatus = MIDIObjectGetStringProperty(&midiEndPoint,kMIDIPropertyDisplayName,name)
// Print the string ... here no surprises I don't know what to write to print the content of the pointer, so it prints the address for the moment
println(name)
インターネット上ではなく、アップル開発者ライブラリで CoreMIDI 関数を使用するためのサンプル コードが見つかりませんでした。私はcppから来て、swiftでは状況が大きく異なるため、本当に混乱しました。
編集 :
Rintaro と Martin が私にまだ問題があると答えた後、私のテストはすべて iOS 8.1 で行われました。
let err = MIDIObjectGetStringProperty(midiEndPoint, kMIDIPropertyDisplayName, &property)
「管理されていない」という結果は、「MIDIObjectRef」に変換できません。MIDIObjectRef は UnsafeMutablePointer<void> なので、「&」を追加しました。
let midiEndPoint = MIDIGetSource(0)
var property : Unmanaged<CFString>?
let err = MIDIObjectGetStringProperty(&midiEndPoint, kMIDIPropertyDisplayName, &property)
現在: 'Unmanaged<MIDIEndpoint>' は '@lvalue inout $T2' に変換できません。最後に、理由を理解せずに、最初の let を var に変更する必要がありました?!?
var midiEndPoint = MIDIGetSource(0)
var property : Unmanaged<CFString>?
let err = MIDIObjectGetStringProperty(&midiEndPoint, kMIDIPropertyDisplayName, &property)
コードはコンパイルおよび実行されますが、MIDIObjectGetStringProperty は IOW または MacErros.h に対応する OSStatus err -50 を返します。
paramErr = -50, /*error in user parameter list*/
そのため、パラメーターは MIDIObjectGetStringProperty が待機しているものではないようです。
MIDIGetNumberOfSources() が 1 を返すため、ソース "0" は私の iPad に存在します。完全なコードは次のとおりです。
var numDestinations: ItemCount = MIDIGetNumberOfDestinations()
println("MIDI Destinations : " + String(numDestinations))
for var i : ItemCount = 0 ; i < numDestinations; ++i{
var midiEndPoint = MIDIGetDestination(i)
var property : Unmanaged<CFString>?
let err = MIDIObjectGetStringProperty(&midiEndPoint, kMIDIPropertyDisplayName, &property)
if err == noErr {
let displayName = property!.takeRetainedValue() as String
println(displayName)
}else{
println("error : "+String(err))
}
}
ディスプレイ:
MIDI Destinations : 1
error : -50
私は本当に何も理解していません...
アップデート :
最後に、Martin は解決策を見つけました。32 ビットと 64 ビットのアーキテクチャには、MIDIObjectRef の 2 つの異なる定義があるようです。古い iPad 2 でコードを実行すると、私のコードは、MIDIGetSource(i) の戻り値が MIDIObjectRef に変換できない 32 ビット モードでコンパイルしようとしました。解決策は、32 ビット アーキテクチャで midi エンドポイントを「安全でないキャスト」することです。
#if arch(arm64) || arch(x86_64)
let midiEndPoint = MIDIGetDestination(i)
#else
let midiEndPoint = unsafeBitCast(MIDIGetDestination(i), MIDIObjectRef.self)
#endif
... または、新しい 64 ビット デバイスを購入するには ...
貴重な助けをありがとう