Obtain a pointer to a C char array in Swift

后端 未结 3 960
故里飘歌
故里飘歌 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 00:51

    Here my suggestion (similar to rintaro's approach, perhaps slightly simpler):

    var err: UnsafeMutablePointer<bson_error_t> = ...
    
    var msg = err.memory.message
    let msgString = withUnsafePointer(&msg) { String.fromCString(UnsafePointer($0)) }
    println(msgString)
    
    0 讨论(0)
  • 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 <stdlib.h>
    #include <string.h>
    #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: 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")
    
    0 讨论(0)
  • 2021-01-06 01:09

    Quick hack to retrieve message String from bson_error_t:

    extension bson_error_t {
        mutating func messageString() -> String? {
            return String.fromCString(
                { (p:UnsafePointer<Void>) in UnsafePointer<CChar>(p) }(&self.message.0)
            )
        }
    }
    
    // Usage:
    var err: UnsafeMutablePointer<bson_error_t> = ...
    ...
    let errMessage = err.memory.messageString()
    
    0 讨论(0)
提交回复
热议问题