Search code examples
cswiftswift3unsafe-pointersunsafemutablepointer

Using C in Swift - strlcpy - Cannot convert value of type 'UnsafeMutablePointer<_>'


I am trying to use strlcpy in Swift 3.0, but keep getting the error "Cannot convert value of type 'UnsafeMutablePointer<_>' to expected argument type 'UnsafeMutablePointer!'"

Here is my code

func login(portal: String, username: String, password: String) {
    var loginEvent = VidyoClientInEventLogIn()
    let portalCArray = UnsafeMutablePointer<Int8>(mutating: (portal as NSString).utf8String!)
    withUnsafeMutablePointer(to: &loginEvent.portalUri) {
        strlcpy($0, portalCArray, MemoryLayout.size(ofValue: $0))
    }
}

where VidyoClientInEventLogIn is:

typedef struct VidyoClientInEventLogIn_
{
    /*! Portal URI, i.e. "https://example.test.com" */
    char portalUri[URI_LEN];
} VidyoClientInEventLogIn;

Solution

  • C arrays are imported to Swift as tuples. But the memory layout of C structures is preserved in Swift, therefore you can use the address of the first tuple element loginEvent.portalUri.0 (which has type CChar aka Int8) as the target address.

    Also you can pass a Swift String directly as argument to a function taking a UnsafePointer<CChar> parameter, a temporary C string representation is created automatically.

    This simplifies things to:

    func login(portal: String, username: String, password: String) {
        var loginEvent = VidyoClientInEventLogIn()
        strlcpy(&loginEvent.portalUri.0, portal, MemoryLayout.size(ofValue: loginEvent.portalUri))
    }