I'm trying to interact with an old C terminal app from Swift. I've successfully integrated the source code and bridged the headers from C to Swift. The code compiles and runs from Xcode 6.3 beta. I've renamed the terminal app's main entry point to:
int initialize(int argc, char **argv);
Nevertheless, I'm struggling to pass the arguments from Swift to this C function. My challenge is to convert the arguments in the right format. Typical input from Swift would look like:
let args = ["-c", "1.2.3.4", "-p", "8000"]
I've tried messing with "cStringUsingEncoding(NSUTF8StringEncoding)" and "withUnsafePointer", but no luck so far. Any help is greatly appreciated!
How Arrays are Passed to Functions in C/C++? A whole array cannot be passed as an argument to a function in C++. You can, however, pass a pointer to an array without an index by specifying the array's name. In C, when we pass an array to a function say fun(), it is always treated as a pointer by fun().
To split a string to an array in Swift by a character, use the String. split(separator:) function. However, this requires that the separator is a singular character, not a string.
Classes are passed by reference. Array and Dictionary in Swift are implemented as structs. Array is not copied / passed by value in Swift - it has very different behavior in Swift compared to regular struct.
Swift's functions have a single return type, such as Int or String , but that doesn't mean we can only return a single value. In fact, there are two ways we can send back multiple pieces of data: Using a tuple, such as (name: String, age: Int) Using some sort of collection, such as an array or a dictionary.
The C function
int initialize(int argc, char **argv);
is mapped to Swift as
func initialize(argc: Int32, argv: UnsafeMutablePointer<UnsafeMutablePointer<Int8>>) -> Int32
This is a possible solution:
let args = ["-c", "1.2.3.4", "-p", "8000"]
// Create [UnsafeMutablePointer<Int8>]:
var cargs = args.map { strdup($0) }
// Call C function:
let result = initialize(Int32(args.count), &cargs)
// Free the duplicated strings:
for ptr in cargs { free(ptr) }
It uses the fact that in strdup($0)
the Swift string $0
is automatically converted to a C string,
as explained in String value to UnsafePointer<UInt8> function parameter behavior.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With