1

I'm trying to use a library which was written in C. I've imported .a and .h files at Xcode project, and checked it works properly. I've already made them working on Objective-C, and now for Swift.

A problem I've got is functions' arguments. There's a function requires an argument widechar(defined as typedef Unsigned short int in Library), which was UnsafeMutablePointer<UInt16> in Swift. The function translates it and return the result.

So I should convert a String to UnsafeMutablePointer<UInt16>. I tried to find the right way to converting it, but I've only got converting it to UnsafeMutablePointer<UInt8>. I couldn't find answer/information about converting String to UnsafeMutablePointer<UInt16>.

Here's a source code I've written.

extension String{
    var utf8CString: UnsafePointer<Int8> {
        return UnsafePointer((self as NSString).utf8String!)
    }
}

func translate(toBraille: String, withTable: String) -> [String]? {
    let filteredString = toBraille.onlyAlphabet

    let table = withTable.utf8CString

    var inputLength = CInt(filteredString.count)
    var outputLength = CInt(maxBufferSize)
    let inputValue = UnsafeMutablePointer<widechar>.allocate(capacity: Int(outputLength))
    let outputValue = UnsafeMutablePointer<widechar>.allocate(capacity: Int(outputLength))

    lou_translateString(table, inputValue, &inputLength, outputValue, &outputLength, nil, nil, 0)
    //This is a function that I should use. 

    let result:[String] = []

    return result
}
2
  • 1
    Not related to your immediate question, but the utf8CString function is unsafe and should not be necessary. You can pass a Swift string directly to a C function taking a UnsafePointer<Int8> argument: lou_translateString(withTable, ...) Commented Feb 21, 2018 at 10:16
  • Oh, I didn't know that. thank you :0 Commented Feb 22, 2018 at 1:05

1 Answer 1

2

You have to create an array with the UTF-16 representation of the Swift string that you can pass to the function, and on return create a Swift string from the UTF-16 array result.

Lets assume for simplicity that the C function is imported to Swift as

func translateString(_ source: UnsafeMutablePointer<UInt16>, _ sourceLen: UnsafeMutablePointer<CInt>,
               _ dest: UnsafeMutablePointer<UInt16>, _ destLen: UnsafeMutablePointer<CInt>) 

Then the following should work (explanations inline):

// Create array with UTF-16 representation of source string:
let sourceString = "Hello world"
var sourceUTF16 = Array(sourceString.utf16)
var sourceLength = CInt(sourceUTF16.count)

// Allocate array for UTF-16 representation of destination string:
let maxBufferSize = 1000
var destUTF16 = Array<UInt16>(repeating: 0, count: maxBufferSize)
var destLength = CInt(destUTF16.count)

// Call translation function:
translateString(&sourceUTF16, &sourceLength, &destUTF16, &destLength)

// Create Swift string from UTF-16 representation in destination buffer:
let destString = String(utf16CodeUnits: destUTF16, count: Int(destLength))

I have assumed that the C function updates destLength to reflect the actual length of the translated string on return.

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.