2015-01-10 20 views
5

Sto utilizzando l'algoritmo dgeev dall'implementazione di LAPACK nel framework Accelerate per calcolare autovettori e autovalori di una matrice. Purtroppo le funzioni di LAPACK non sono descritte nella documentazione Apple con un semplice collegamento a http://netlib.org/lapack/faq.html incluso.UnsafeMutablePointer <Int8> da String in Swift

Se si cerca, i primi due argomenti in dgeev sono caratteri che indicano se calcolare gli autovettori o meno. In Swift, sta chiedendo UnsafeMutablePointer<Int8>. Quando uso semplicemente "N", ottengo un errore. La funzione dgeev e l'errore sono descritti nella seguente schermata enter image description here

Cosa devo fare per risolvere questo problema?

risposta

3

Il "problema" è che i primi due parametri vengono dichiarati come char * e non come const char *, anche se le stringhe non vengono modificati dalla funzione:

int dgeev_(char *__jobvl, char *__jobvr, ...); 

viene mappata Swift come

func dgeev_(__jobvl: UnsafeMutablePointer<Int8>, __jobvr: UnsafeMutablePointer<Int8>, ...) -> Int32; 

Una possibile soluzione è

let result = "N".withCString { 
    dgeev_(UnsafeMutablePointer($0), UnsafeMutablePointer($0), &N, ...) 
} 

All'interno del blocco, $0 è un puntatore a un array con terminazione NUL di char con la rappresentazione UTF-8 della stringa.


Nota:dgeev_() non modifica le stringhe punta il primi due argomenti, quindi "deve essere" dichiarati

int dgeev_(const char *__jobvl, const char *__jobvr, ...); 

che verrebbe mappato a Swift come

func dgeev_(__jobvl: UnsafePointer<Int8>, __jobvr: UnsafePointer<Int8>, ...) -> Int32; 

e in tal caso si potrebbe semplicemente chiamarlo come

let result = dgeev_("N", "N", &N, ...) 

perché le stringhe Swift vengono convertiti automaticamente UnsafePointer<Int8>), come spiegato in String value to UnsafePointer<UInt8> function parameter behavior.

3

E 'brutto, ma è possibile utilizzare:

let unsafePointerOfN = ("N" as NSString).UTF8String 
var unsafeMutablePointerOfN: UnsafeMutablePointer<Int8> = UnsafeMutablePointer(unsafePointerOfN) 

e utilizzare unsafeMutablePointerOfN come parametro al posto di "N".

+0

C'è almeno un problema teorico con questa soluzione: la stringa restituita da '.UTF8String' è garantita solo finché esiste l'oggetto' NSString', che potrebbe essere distrutto immediatamente perché non vi è alcun riferimento a dopo la prima riga. Molto probabilmente questo non accadrà qui perché la stringa qui è una costante letterale. –