How to call C variadic functions from Swift?

In this article we’re going to create a Swift wrapper function for a C function that use the ... syntax for variadic arguments:

int my_sum(int n, ...);

... variadic arguments syntax is not supported by default in Swift, you will get compiler errors like this:

'my_sum' is unavailable: Variadic function is unavailable

There’s a way to workaround this limitation, if you can modify the C function to take va_list as parameter.

Create a new C function with va_list

The original function looks like this:

int my_sum(int n, ...)
{
int result = 0;

va_list args;
va_start(args, n);

for(int i = 0; i < n; i++) {
result += va_arg(args, int);
}

va_end(args);

return result;
}

To avoid duplicating the logic, we can create a new version take a va_list as parameter, and call the new version from the original function:

// New version 
int my_vsum(int n, va_list arguments)
{
int result = 0;

for(int i = 0; i < n; i++) {
result += va_arg(arguments, int);
}

return result;
}

// Original
int my_sum(int n, ...)
{
va_list args;
va_start(args, n);

int result = my_vsum(n, args);

va_end(args);

return result;
}

Create a Swift wrapper with CVarArg

func mySwiftSum(_ n: Int32, _ arguments: CVarArg...) -> Int32 {
return withVaList(arguments) { my_vsum(n, $0) }
}

Now we can use this function in Swift:

let sum = mySwiftSum(5, 1, 2, 3, 4, 5)
print("sum = \(sum)")
// Prints "sum = 15"

References