Obtain a pointer to a C char array in Swift

后端 未结 3 962
故里飘歌
故里飘歌 2021-01-06 00:19

A have a structure like this (defined in bson.h of mongodb c driver):

typedef struct
{
  uint32_t domain;
  uint32_t code;
  char message[504];
} bson_error_         


        
3条回答
  •  花落未央
    2021-01-06 01:07

    It's not pretty, not intuitive, but it's doable. Purely in Swift, no C glue code needed. A minimal demo:

    b.h

    typedef struct {
        int n;
        char s[8];
    } Bridged;
    
    Bridged *make_b(void);
    

    b.c

    #include 
    #include 
    #include "b.h"
    
    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) -> [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 b.h
    $ clang -O2 -c b.c -o b.c.o
    $ xcrun swiftc b.o b.c.o -o b
    

    Run:

    $ ./b
    Optional("foobarz")
    

提交回复
热议问题