It is not beautiful, not intuitive, but it is doable. Purely in Swift, no glue C code required. Minimal demo:
bh
typedef struct { int n; char s[8]; } Bridged; Bridged *make_b(void);
bc
#include <stdlib.h> #include <string.h> #include "bh" Bridged *make_b(void) { Bridged *p = calloc(sizeof(*p), 1); memcpy(p->s, "foobarz", 8); return p; }
b.swift:
// half compile-time, half run-time black magic func toCharArray<T>(t: T) -> [CChar] { var a: [CChar] = [] let mirror = reflect(t) for i in 0 ..< mirror.count { a.append(mirror[i].1.value as CChar) } return a } let b = make_b().memory.s // bridged tuple of 8 chars let a = toCharArray(b) // Swift array of (8) CChars let s = String.fromCString(a) // proper Swift string println(s)
Compile:
$ xcrun swiftc -O -c b.swift -import-objc-header bh $ clang -O2 -c bc -o bco $ xcrun swiftc bo bco -ob
Run:
$ ./b Optional("foobarz")
source share