Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting array of C strings to Swift string array

In Swift 3, C function with signature const char *f() is mapped to UnsafePointer<Int8>! f() on import. It's result can be converted to a Swift string as:

let swiftString = String(cString: f())

The question is, how a NULL terminated C array of C strings can be mapped to Swift array of strings?

The original C signature:

const char **f()

Imported Swift signature:

UnsafeMutablePointer<UnsafePointer<Int8>?>! f()

Swift array of strings:

let stringArray: [String] = ???
like image 542
Zmey Avatar asked Jul 17 '16 15:07

Zmey


People also ask

How do I convert an array to a string in Swift?

To convert an array to string in Swift, call Array. joined() function.

Can we convert string array to string?

We can use Arrays. toString method that invoke the toString() method on individual elements and use StringBuilder to create String. We can also create our own method to convert String array to String if we have some specific format requirements.

How do I convert an array to a string?

toString() method: Arrays. toString() method is used to return a string representation of the contents of the specified array. The string representation consists of a list of the array's elements, enclosed in square brackets (“[]”). Adjacent elements are separated by the characters “, ” (a comma followed by a space).

How do you create an array of arrays in Swift?

In Swift, creating a multi-dimensional array is just a matter of adding another set of brackets. For example, to turn our [String] array into an array of arrays, you would just write [[String]] .


1 Answers

There is no built-in method as far as I know. You have to iterate over the returned pointer array, converting C strings to Swift Strings, until a nil pointer is found:

if var ptr = f() {
    var strings: [String] = []
    while let s = ptr.pointee {
        strings.append(String(cString: s))
        ptr += 1
    }
    // Now p.pointee == nil.

    print(strings)
}

Remark: Swift 3 uses optional pointers for pointers that can be nil. In your case, f() returns an implicitly unwrapped optional because the header file is not "audited": The compiler does not know whether the function can return NULL or not.

Using the "nullability annotations" you can provide that information to the Swift compiler:

const char * _Nullable * _Nullable f(void);
// Imported to Swift  as
public func f() -> UnsafeMutablePointer<UnsafePointer<Int8>?>?

if the function can return NULL, and

const char * _Nullable * _Nonnull f(void);
// Imported to Swift  as
public func f() -> UnsafeMutablePointer<UnsafePointer<Int8>?>

if f() is guaranteed to return a non-NULL result.

For more information about the nullability annotations, see for example Nullability and Objective-C in the Swift blog.

like image 80
Martin R Avatar answered Sep 22 '22 23:09

Martin R