You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Swift 5中调用可变参数C函数evolis_get_devices?

解决Swift 5调用C可变参数函数evolis_get_devices的不可用问题

问题分析

你遇到的'evolis_get_devices' is unavailable: Variadic function is unavailable错误,根源是Swift对C风格的可变参数函数(带...语法)支持有限,无法直接调用。结合C函数的注释“Takes a list of model ended by zero”,该函数的可变参数需要传入一系列设备模型标识,最后以0结尾,而非你当前传入的count变量——实际上count是函数的返回值,用于获取设备数量。

解决方案

方法1:C封装层中转(推荐)

通过编写简单的C封装函数,将可变参数转换为固定参数形式,是最稳妥的解决方式,避免Swift与C可变参数的兼容性问题。

  1. 创建C封装文件:

    • 头文件EvolisWrapper.h:
      #include "evolis_sdk.h" // 引入原Evolis SDK头文件
      
      EVOLIS_LIB int evolis_get_devices_wrapper(evolis_device_t** devices);
      
    • 实现文件EvolisWrapper.c:
      #include "EvolisWrapper.h"
      
      int evolis_get_devices_wrapper(evolis_device_t** devices) {
          // 传入0作为可变参数结尾,获取所有设备(如需指定模型,可替换为对应标识,如"PM40", 0)
          return evolis_get_devices(devices, 0);
      }
      
  2. Swift中调用封装后的函数:

    public static func getDevices() -> [Device] {
        var devices: UnsafeMutablePointer<evolis_device_t>?
        let count = evolis_get_devices_wrapper(&devices)
    
        var devicesList: [Device] = []
    
        if count > 0 {
            for i in 0..<count {
                let device = Device(device_c: devices![Int(i)])
                devicesList.append(device)
            }
        }
    
        evolis_free_devices(devices)
    
        return devicesList
    }
    

方法2:使用Swift的withVaList(兼容性差,不推荐)

如果不想新增C文件,可以尝试用Swift的withVaList构造可变参数列表,但这种方式对C函数的参数要求严格,且跨版本兼容性不佳:

public static func getDevices() -> [Device] {
    var devices: UnsafeMutablePointer<evolis_device_t>?
    var count: Int32 = 0

    // 构造以0结尾的可变参数列表
    withVaList([0]) { vaList in
        count = evolis_get_devices(&devices, vaList)
    }

    var devicesList: [Device] = []

    if count > 0 {
        for i in 0..<count {
            let device = Device(device_c: devices![Int(i)])
            devicesList.append(device)
        }
    }

    evolis_free_devices(devices)

    return devicesList
}

注意事项

  • 原C函数的count是返回值,不是传入参数,你之前的代码逻辑存在错误,需要修正。
  • 若需指定特定设备模型,可在C封装函数的evolis_get_devices调用中传入对应模型字符串,最后以0结尾,例如evolis_get_devices(devices, "PM40", "Zenius", 0)。

内容的提问来源于stack exchange,提问作者nemoxi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 21:05:24