2015-05-05 7 views
10

ich eine C-Funktion zu Swift abgebildet haben wie folgt definiert:Swift convert String UnsafeMutablePointer <Int8>

func swe_set_eph_path(path: UnsafeMutablePointer<Int8>) -> Void 

ich einen Weg zur Funktion zu übergeben bin versucht, und haben versucht:

 var path = [Int8](count: 1024, repeatedValue: 0); 
     for i in 0...NSBundle.mainBundle().bundlePath.lengthOfBytesUsingEncoding(NSUTF16StringEncoding)-1 
     { 
      var range = i..<i+1 
      path[i] = String.toInt(NSBundle.mainBundle().bundlePath[range]) 
     } 
     println("\(path)") 
     swe_set_ephe_path(&path) 

aber auf der Weg [i] Zeile bekomme ich den Fehler:

'subscript' is unavailable: cannot subscript String with a range of Int

swe_set_ephe_path(NSBundle.mainBundle().bundlePath) 
noch

swe_set_ephe_path(&NSBundle.mainBundle().bundlePath) 

nicht funktionieren entweder

Neben nicht funktioniert, ich fühle mich hat es doch ein besserer sein, weniger gewundener Weg, dies zu tun. Vorherige Antworten auf StackOverflow mit CString scheinen nicht mehr zu funktionieren. Irgendwelche Vorschläge?

+0

Bitte, wenn der Code zeigt, zeigen immer _REAL_werte Code. Ihre Deklaration ist nicht real - es ist keine gültige Swift-Funktionsdeklaration, und ich vermute, dass der Funktionsname falsch ist. Code nicht in Stapelüberlauf eingeben; Kopieren und fügen Sie _real_ code ein. Immer. – matt

Antwort

15

Previous answers on StackOverflow using CString don't seem to work anymore

Dennoch ist UnsafePointer<Int8> ein C-String. Wenn unbedingt Ihren Kontext eine UnsafeMutablePointer erfordert, nur zwingen, wie folgt aus:

let s = NSBundle.mainBundle().bundlePath 
let cs = (s as NSString).UTF8String 
var buffer = UnsafeMutablePointer<Int8>(cs) 
swe_set_ephe_path(buffer) 

Natürlich habe ich nicht Ihre swe_set_ephe_path haben, aber es funktioniert in meinem Test in Ordnung, wenn es so stubbed ist:

+0

Das schien großartig zu funktionieren. Es verwendet Aspekte von Swift, die mir nicht vertraut waren, und so ist es für die Beantwortung der Frage und eine Lektion zu fortgeschritteneren Sprachaspekten ein Gewinner in beiden Punkten. Vielen Dank! – SteveFerg

+0

Erfreut zu helfen. Alles kam direkt aus meinem Buch, hier: http://www.apeth.com/swiftBook/apa.html#_c_data_types Lassen Sie mich wissen, dass Sie weitere Fragen dazu haben, was der Code tut. – matt

+0

Verdammt! Ich habe gerade dieses Buch gekauft und gelesen, aber nicht den Anhang angeschaut! Ich werde jetzt ... – SteveFerg

6

Es ist wirklich äußerst irritierend der Bibliothek, die Sie verwenden, dass es (in der C-Deklaration) eine char * path statt const char * path erfordert. (Dies setzt voraus, dass die Funktion die Eingabezeichenfolge nicht mutiert - wenn dies der Fall ist, befinden Sie sich in einer ganz anderen Situation).

Wenn es nicht täte, würde die Funktion zu Swift kommen wie:

// note, UnsafePointer not UnsafeMutablePointer 
func swe_set_eph_path(path: UnsafePointer<Int8>) -> Void 

und man konnte dann auf Swift implizite Konvertierung verlassen:

let str = "blah" 
swe_set_eph_path(str) // Swift implicitly converts Strings 
         // to const C strings when calling C funcs 

Aber man kann eine unsichere Umwandlung tun ganz einfach, in Kombination mit der withCString Funktion:

str.withCString { cstr in 
    swe_set_eph_path(UnsafeMutablePointer(cstr)) 
} 
+0

Ja, ich dachte daran, ihn 'withCString' als eine Swiftier-Alternative zu' (s als NSString) .UTF8String' zu zeigen - ich habe das wirklich hineingesteckt, und dann habe ich es wieder rausgenommen. :) - Ich habe keine Ahnung, warum er einen unsicheren veränderlichen Zeiger braucht; Ich gab ihm nur eins, weil er sagte, dass er eins brauchte. – matt

+0

Abgesehen von seiner puren Schnelligkeit bevorzuge ich den 'withCString', da dies das Scoping explizit macht. Ich werde sehr nervös wegen dem '(str als NSString) .UTF8String'. Wann wird diese 'NSString'-Version zerstört, vermutlich mit dem Speicher, der der UTF-8-Version zugewiesen wurde? Es ist nicht klar. Möglicherweise bevor Sie eine Chance bekommen, es zu verwenden ... –

+0

Tatsächlich wurde es nie zugewiesen. Es ist nur ein Blick auf die ursprüngliche Saite. Ich vertraue dem Compiler, die ursprüngliche Saite nicht zu optimieren! Vielleicht sollte ich nicht. – matt

5

ich hatte eine statische Bibliothek (someLibrary.a), geschrieben in C++ für iOS kompiliert. Die Header-Datei (someLibrary.h) hatte eine Funktion wie folgt ausgesetzt:

extern long someFunction(char* aString);

Die Erklärung in Swift sieht wie folgt aus:

Int someFunction(aString: UnsafeMutablePointer<Int8>)

ich eine Erweiterung String gemacht:

extension String { 
    var UTF8CString: UnsafeMutablePointer<Int8> { 
     return UnsafeMutablePointer((self as NSString).UTF8String) 
    } 
} 

Also dann kann ich die Meth anrufen od etwa so:

someFunction(mySwiftString.UTF8CString)