Umwandlung einer C-char-array zu einem String
Ich habe einen Swift-Programm, das interop mit einer C Bibliothek. Diese C-Bibliothek gibt eine Struktur mit einem char[]
array-innen, wie diese:
struct record
{
char name[8];
};
Die definition ist korrekt importiert Swift. Aber das Feld wird interpretiert als ein Tupel von 8 Int8
Elemente (typisierte (Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8)
), die ich habe keine Ahnung, wie das zu verwandeln in eine String
mit Swift.
Gibt es keine String
Initialisierung nimmt eine Int8
Tupel, und es scheint nicht möglich, einen Zeiger auf das erste element des Tupels (da können Typen heterogenen, das ist nicht wirklich verwunderlich).
Jetzt meine beste Idee ist, erstellen Sie ein kleines C-Funktion akzeptiert einen Zeiger auf die Struktur selbst und zurück name
als char*
pointer statt einem array, und gehen Sie mit.
Gibt es, allerdings sind Reine Swift Weg, es zu tun?
wenn ich war auf der Suche für how to convert a C char-array, um einen Swift string, schaute ich mich nach tags "c" und "swift" für sicher.
Es gibt nichts C über das byte-array, aber Sie haben eine Beschreibung, die es gilt in C, C++, objective-C, objective-C++ und so weiter. Macht es nicht zu einem C-Frage.
Ich kenne niemand, der bezieht sich auf diese als "C++ - arrays" oder "Objective-C-arrays" oder "Objective-C++ - arrays", und ich kenne keine andere definition von "C-Arrays". Wenn ich eine Lösung gesucht, die ich verwendet, "C-Arrays" in meine Suchbegriffe, und es sei denn, ich bin ein Ausreißer, ich glaube die nächste person mit dem gleichen problem wird das gleiche tun. Ich denke, dass die tags sind das wichtigste für die Suchanfragen, und dass Ihre Kategorisierung Zweck kommt an zweiter Stelle.
Wenn etwas oft beschrieben mit C als synonym für low-level und native markiert C, würde der Sumpf der C-tag mit nur über alles, was mit native interop. Sehr schlechte Idee.
InformationsquelleAutor zneak | 2014-12-13
Du musst angemeldet sein, um einen Kommentar abzugeben.
Den C-array
char name[8]
importiert Swift als ein Tupel:Die Adresse von
name
ist die gleiche wie die Adresse desname[0]
, undSwift bewahrt das speicherlayout von Strukturen importiert aus C,
bestätigt durch Apple-Ingenieur Joe Groff:
Als Folge, können wir übergeben die Adresse von
record.name
,Umgerechnet auf einen
UInt8
Zeiger,die String-Initialisierung:
HINWEIS: Es wird davon ausgegangen, dass die bytes in
name[]
sind eine gültige NULL-terminiertem UTF-8-Sequenz.record
muss werden von Mutationen (deklariert mitvar
) oder der Swift-compiler schießt einen seltsamen Fehler.Sie haben Recht, ich haben Hinzugefügt, dass die Informationen für die Antwort.
Ich glaube, das wird funktionieren, aber es ist dokumentiert, dass ein Tupel im Speicher zusammenhängend sind? Mit arrays, die Sie nicht bekommen, die Zusicherung, es sei denn, Sie rufen
withUnsafeBufferPointer
, aber tuple-Implementierung nicht dokumentiert worden, so weit ich erzählen kann.Das ist eine gute Frage. Es scheint mir plausibel, da die Tupel ist (in diesem Fall) der Rasche Blick auf ein C-array
char name[8]
.Eigentlich ist es wird gewährleistet, wenn die Struktur importiert aus C. ich habe aktualisiert die Antwort entsprechend mit einem Verweis, und vereinfacht den code.
InformationsquelleAutor Martin R
Können Sie sammeln ein Tupel in einem array mit der Swift-variadic-parameter syntax:
Was Konstrukt ist
let (int8s: Int8...)
? Istlet (name : type) = exp
im Allgemeinen die gleichen wielet name : type = expr
?In diesem Fall würden Sie brauchen, um es zu tun, inline, da Sie mit einer Funktion, die Sie haben zu geben die richtige Anzahl von Elementen, die sich jeweils entsprechen bestimmte Tupel stelligkeit. Ich modifiziert habe meine Antwort um zu zeigen, was Sie tun können.
Der name ist Tupel-Dekomposition. Sie können ziehen Sie die Dinge auf interessante Weise mit dieser Technik versuchen:
let (_, second, _, fourth, theRest: Int...) = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Als der Swift 2 in der Xcode-7b1 beta, das funktioniert nicht mehr.
InformationsquelleAutor Nate Cook
Ich bin daran interessiert diese sich für meine Zwecke als gut, so dass ich Hinzugefügt eine neue Funktion:
Ich diese Funktion aufrufen mit:
die resultierende Ausgabe ist:
testSwiftString = test
InformationsquelleAutor jwlaughton
Swift 3. Nur die reflektion verwendet. Diese version Stoppt Bau der string-wenn es auf einem null-byte. Getestet.
InformationsquelleAutor rosstulloch
Gerade habe ich erlebt ein ähnliches Problem mit Swift 3. (3.0.2). Ich war versucht, zu konvertieren, eine Reihe von CChar, [CChar], um einen String in Swift. Es stellt sich heraus, Swift 3 hat eine String-Initialisierung, die ein cString.
Beispiel:
Ergebnisse in
= Optional([97, 98, 99, 0])
b = Optional("abc")
Beachten Sie, dass der cString-Funktion auf den String-Ergebnisse wahlweise in einem. Es muss erzwungen werden, ausgepackt, wenn in der Zeichenfolge.init-Funktion erstellen. b. Und b ist ebenfalls Optional... das heißt die beiden konnten am Ende als null, so dass Fehler überprüfen sollte auch verwendet werden.
InformationsquelleAutor Steve Rogers
Versuchen Sie dies:
UnsafePointer<UInt8>
, es ist ein Tupel von 8Int8
Elemente, so dass diese Methode nicht mein problem lösen. Neben derString
Klasseinit?(UTF8String: UnsafePointer<CChar>)
failable Initialisierer, tut genau dies.In meiner Anwendung, die ich benötigen für die Anmeldung die aktuelle OpenGL-version, um sicher zu sein das pixel format richtig gesetzt werden. Ich mache das mit lassen glVersionCString:UnsafePointer<UInt8> = glGetString(GLenum(GL_VERSION)). Der compiler wird nicht lassen Sie mich werfen die Rückkehr von glGetString als UnsafePointer<CChar>, so kann ich nicht verwenden, das Swift-String-Initialisierung. Das ist der Grund für diese Funktion.
Ich bin nicht in Frage, den nutzen der Funktion in Ihrem bestimmten Fall, aber es gilt hier nicht. Dies funktioniert für Sie, weil
glGetString
gibt einen Zeiger. Diestruct
ich zu tun habe, hat ein array-Feld, welches ganz anders als ein Zeiger-Feld. Wie ich schon sagte, das Feld Typ wie gesehen von Swift ist(Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8)
, nichtUnsafePointer<UInt8>
.InformationsquelleAutor jwlaughton
Hier ist eine Lösung, die ich kam mit die verwendet reflektion, um tatsächlich zu konvertieren, die Tupel in einer [Int8] (siehe Jeder Weg, um die Iteration eines Tupels in swift?), und dann wandelt es in eine Zeichenfolge mit fromCString... () - Methoden.
InformationsquelleAutor joeybladb