Convert string to UnsafeMutablePointer <char_t> in Swift

I am working with a third-party API. I am trying to call one of the functions with a simple string. Something like that:

some_c_func("aString"); 

I get a build error:

 Type 'UnsafeMutablePointer<char_t>' does not conform to protocol 'StringLiteralConvertible' 

I saw some suggestions on using utf8 for String or similar conversions, which are almost there, but with the following error:

 some_c_func("aString".cStringUsingEncoding(NSUTF8StringEncoding)); 'UnsafePointer<Int8>' is not convertible to 'UnsafeMutablePointer<char_t>' 

How to create an UnsafeMutablePointer?

+5
source share
3 answers

It all depends on what char_t .

If char_t converted to Int8 , then the following will work.

 if let cString = str.cStringUsingEncoding(NSUTF8StringEncoding) { some_c_func(strdup(cString)) } 

It can be minimized to

 some_c_func(strdup(str.cStringUsingEncoding(NSUTF8StringEncoding)!)) 

WARNING! This second method will fail if func cStringUsingEncoding(_:) returns nil .


Update for Swift 3 and fix memory leak

If the string C is only needed in the local area, then strdup() not required.

 guard let cString = str.cString(using: .utf8) else { return } some_c_func(cString) 

cString will have the same memory life cycle as str (at least at least).

If line C should be outside the local area, you will need a copy. This copy must be released.

 guard let interimString = str.cString(using: .utf8), let cString = strdup(interimString) else { return } some_c_func(cString) //… free(cString) 
+1
source

it may be easier than many other APIs to pass strings as char * types, and swift treats them as unsafe.

try updating the C API (good) or cracking its header files (bad) to declare them as const char *.

in my experience this allows you to pass standard string string types directly to the C API.

obviously, a constant is required to fit the protocol.

+1
source

I have not tried passing strings like this, but I have a C function that I call from Swift, which requires much more parameters than shown here, among which there is a link to a buffer like Swift C for storing a string error. The compiler does not complain and the function call works. We hope this helps you get closer to the answer, and you can provide an update with the final answer or someone else.

  var err = [CChar](count: 256, repeatedValue: 0) var rv = somefunc((UnsafeMutablePointer<Int8>)(err)) if (rv < 0) { println("Error \(err)") return } 
0
source

Source: https://habr.com/ru/post/1210149/


All Articles