从 Swift 调用 C 可变参数函数

Mor*_*ten 2 variadic-functions swift

我正在尝试使用以下签名从 Swift 调用 C 函数(外部 API):

extern void k(int, const char*, ...)
Run Code Online (Sandbox Code Playgroud)

我这样调用 C 函数:

func send(query: String, args: CVarArg...) {
    let query2 = UnsafeMutablePointer(mutating: query.cString(using: String.defaultCStringEncoding))
    let result = k(0, query2, args)
}
Run Code Online (Sandbox Code Playgroud)

但出现错误'k' is unavailable: Variadic function is unavailable

我不确定这是否可行,因为 C API 不接受va_list( http://swiftdoc.org/v3.1/protocol/CVarArg/ )。如果需要的话,我不介意用 C 语言编写包装函数。

Mar*_*n R 6

您不能调用从 Swift 获取变量参数列表的 C 函数。您需要一个带有参数的变体va_list(类似于printfvprintf):

int kv(int n, const char *s, va_list args) {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

原始函数k可以转发到kv

int k(int n, const char* s, ...) {
    va_list args;
    va_start(args, s);
    int result = kv(n, s, args);
    va_end(args);
    return result;
}
Run Code Online (Sandbox Code Playgroud)

现在kv可以从 Swift 调用:

func send(query: String, args: CVarArg...) {
    let result = withVaList(args) {
        kv(0, query, $0)
    }
}
Run Code Online (Sandbox Code Playgroud)

(您可以将 SwiftString直接传递给带有参数的 C 函数 const char *,编译器会插入必要的代码来创建一个以 null 结尾的 C 字符串的临时表示。)