How to pass double pointer to char to c function using swift

Hi... i am new to swift . I am trying to call c function using swift .

c function declaration

extern int pointerfunc(int p0, char** p1);

I am using .dylib for importing function in swift so , i have created typealias for c function

typealias pointerfunc = @convention(c)(CInt,CChar) -> CInt

Swift code that i am using for calling c function and creating pointer is
//Created variable
var error = "Error received"
//
withUnsafePointer(to: &error) {
errorvalue in withUnsafePointer(to: errorvalue){
errordoublepointer in
//Calling c function using pointer
print(point(3,errordoublepointer))
}

                            }

How can i pass double pointer to char to c function ?

First up, if there’s a way you to move your thread over to Using Swift, you should do so. Your question is about how to achieve something in Swift as it currently stands, and that’s perfect for the Using Swift area.

Next, I recommend that you temporarily avoid dealing with function pointers. Rather, start by declaring your function in C and then accessing it via a bridging header. That allows you to focus on the pointer-to-pointer-to-char problem, and leave the function pointer issues for later. Thus, I added a prototype like this to my bridging header:

extern int something(int somethingElse, char **errorStringPtr);

Finally, it’s hard to give a definitive answer because pointer-to-pointer-to-char can have lots of different semantics in C. It looks like the second parameter is a way for the C function to return you an error string. If so, you might write the code like this:

var errorCStrQ: UnsafeMutablePointer<CChar>? = nil
let result = something(1, &errorCStrQ)
if let errorCStr = errorCStrQ {
    let errorStr = String(cString: errorCStr)
}

However, this is still very fuzzy. For example:

  • Is it safe to look at the error regardless of the function result? The standard Cocoa convention is that you should ignore an indirect error like this if the function succeeds.

  • What’s the memory management for the ‘returned’ C string? Here I’m doing nothing with it, but it’s possible that you might need to free it.

Share and Enjoy

Quinn “The Eskimo!” @ DTS @ Apple

4 Likes

I agree with Quinn that it would be better to get a prototype for your function by importing a C header instead of trying to declare the function type in Swift.

The low-level answers to your question are that:

  • CChar is the Swift type equivalent to char, not char**; you need UnsafeMutablePointer<UnsafeMutablePointer<CChar>> (or just UnsafeMutablePointer<UnsafePointer<CChar>> if it should really be const char **, or UnsafePointer<UnsafePointer<CChar>> if it should really be const char * const *). You may also need to add some amount of optionality to get the type you want.
  • The way to get a C string pointer from a Swift String is the withCString method; that'll give you a (temporary) UnsafePointer<UInt8>. The right way to get a pointer-to-pointer depends on why the function requires a pointer-to-pointer. Does it really expect an array, and does that array need to be null-terminated? If so, you'll need to make an array, like var array = [cString], and then pass &array to the C function.
2 Likes

That can be done by anyone by clicking the pencil to edit the thread’s title. Once in edit mode, fields to modify the category and tags appear as well.

Some trust level may need to be earned before you can do that to others’ threads; I don’t really know. For the longest time I thought I lacked the necessary permissions, simply because it appeared to be absent from my interface, but that turned out to be incorrect when I did finally find it and realized it was just in an unintuitive location.

Terms of Service

Privacy Policy

Cookie Policy