5

In my swift app project, I have to interact with C APIs. One of the C function takes a char pointer as input, therefore I have to convert my swift string into char pointer. But I don't know how to do it properly.

Here's my sample code:

var user_id_ptr : UnsafeMutablePointer<CChar> = UnsafeMutablePointer.alloc(100)
var cusID = "123"  
user_id_ptr.memory = cusID.cStringUsingEncoding(NSUTF8StringEncoding)!

And I always got this error: Cannot assign a value of type '[CChar]' to a value of type 'CChar'

I also check the answer in: UnsafeMutablePointer<Int8> from String in Swift

Above answer is slightly different from mine. The example above is for only one character, but I have a string. Also, I have to pass multiple arguments to the function, I can't use something like let result = "N".withCString { dgeev_(UnsafeMutablePointer($0), UnsafeMutablePointer($0), &N, ...) }. Please show me some example for how to complete this.

3
  • 1
    Depending on whether the C function takes a char * or a const char *, either stackoverflow.com/questions/27876179/… or stackoverflow.com/questions/27063569/… should solve your problem. Commented Jul 13, 2015 at 8:08
  • Thanks for ur answer, but I still got some problem. The example u post is for only one character, but I have a string. Also, I have to pass multiple arguments to the function, I can't use something like let result = "N".withCString { dgeev_(UnsafeMutablePointer($0), UnsafeMutablePointer($0), &N, ...) }. Please show me some example for how to complete this. Commented Jul 14, 2015 at 3:58
  • The same technique works with (multiple) strings, but I have added it as an answer for your convenience :) Commented Jul 14, 2015 at 5:47

1 Answer 1

14

If the C function does not mutate the strings passed as arguments, then the parameters should be declared as const char *, for example

int func1(const char *s1, const char *s2);

and in that case you can simply pass Swift strings which are automatically converted (compare String value to UnsafePointer<UInt8> function parameter behavior):

let str1 = "first string argument"
let str2 = "second string argument"

let result1 = func1(str1, str2)

If the function parameters are declared as char *

int func2(char *s1, char *s2);

then you have to use withCString() to obtain a temporary representation of the string as a NUL-terminated array of UTF-8 characters:

let str1 = "first string argument"
let str2 = "second string argument"

// Swift 2:
let result2 = str1.withCString { s1 in
    str2.withCString { s2 in
        func2(UnsafeMutablePointer(s1), UnsafeMutablePointer(s2))
    }
}

// Swift 3:
let result2 = str1.withCString { s1 in
    str2.withCString { s2 in
        func2(UnsafeMutablePointer(mutating: s1), UnsafeMutablePointer(mutating: s2))
    }
}

Note that this still assumes that the function does not mutate the passed strings, the UnsafeMutablePointer() conversion is only needed to make the compiler happy.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.