Developing software in the Real World

Wrapping variadic functions for use in Swift

As I noted in my post about getting libcurl working with Swift, curl_easy_setopt() is a variadic function which means that Swift will not import it. If you try to use it you get this error:

It’s mildly annoying as curl_easy_setopt only ever takes three parameters! I assume that it’s marked as a variable argument function because the last parameter can be any type?

To solve this, I wrote a simple C library that exposes new functions that are not variadic and take a known type as their last parameter as I’m not sure if I can write a function in C that takes an unknown type and use it in Swift in a sane way.

Create a static C library

So, to start simply, we’ll create a library that implements curl_easy_setopt_string and curl_easy_setopt_bool.

The C for this is easy enough. Start with a mycurl.h file:

The C file, mycurl.c is equally simple:

(I don’t think I’ll get any awards for this code!)

To build the C file into an object file we use:


and then we turn it into a static library using

One limitation of the Swift Package Manager (as far as I can tell) is that it will only link libraries that are LD_LIBARARY_PATH. Hence, we need to copy libmycurl.a to /usr/local/lib:

Integrate our library with Swift

To integrate our library with Swift, we can simply update the CCurl package that we created earlier.

The module.modulemap file we have so far is:

and we update it with the new information, so that it now looks like:

Note that it seems happy that the header is a relative path, but that the link to mycurl (it doesn’t need the prepended “lib“) cannot be relative. If there’s a way to make it relative, please let me know!

Having updated our CCurl module, we tag it with version 0.0.2 and can then use it in our app and actually load a webpage!

Update the app’s main.swift file so that it is more complete:

A quick swift build later and you can run it:

For me, the output looks like this:

Swift curl1

Conclusion

I’ve wrapped up all that I’ve learnt so far into a repository on GitHub called CCurl, so all you actually need to do is add it as a dependency in your Package.swift:

Next on my list is working out how to do a callback so that I can collect the website’s HTML rather than it echoing to stdout!

2 thoughts on “Wrapping variadic functions for use in Swift

Thoughts? Leave a reply

Your email address will not be published. Required fields are marked *