嗨我正在尝试使用 Swift 4 包装一个 C api
Swift 已导入具有以下签名的函数。
public typealias indicator = @convention(c) (Int32, UnsafePointer<UnsafePointer<Double>?>?, UnsafePointer<Double>?, UnsafePointer<UnsafeMutablePointer<Double>?>?) -> Int32
根据 C 库文档,签名如下:
int indicator(int size,
double const *const *inputs,
double const *options,
double *const *outputs);
值得注意的是,函数的int
返回是c风格的函数的错误类型,实际返回在outputs
指针中
那么假设我创建了以下 Swift 类型
let inputs: [[Double]] = []
let options: [Double] = []
var outputs: [[Double]] = []
使用一些适当的值,那么我应该能够执行以下操作:(注意info.pointee.indicator
是导入的函数)
internal func calculateIndicator(options opts: [Double], input inputs: [[Double]], output outPuts: inout [[Double]]) -> [[Double]]? {
guard let sz = inputs.first?.count else {fatalError("Must supply a [[Double]] input param")}
let inputPointer = UnsafePointer<[Double]>(inputs)
let optionsPointer = UnsafePointer<Double>(opts)
var outputPointer = UnsafeMutablePointer<[Double]>(&outPuts)
let val = info.pointee.indicator(Int32(sz), inputPointer, optionsPointer, outputPointer)
// do something with the outputs and return the values
}
但是编译器抱怨以下错误:
Cannot invoke 'indicator' with an argument list of type '(Int32, UnsafePointer<[Double]>, UnsafePointer<Double>, UnsafeMutablePointer<[Double]>)'
当我传递了不正确的类型(我认为)时,这种方式是有道理的。
那么除了内存管理问题之外,我将如何将[[Double]]
类型转换为例如UnsafePointer<UnsafeMutablePointer<Double>>
指针?
根据此处的文档Calling Functions With Pointer Parameters我应该能够通过隐式桥接来做到这一点,但似乎不是,也许我应该只创建指针类型而不是尝试从 Swift 转换?
在此先感谢,我确定我缺少一些简单的东西。
C API 本身如下:
typedef int (*indicator_function)(int size,
double const *const *inputs,
double const *options,
double *const *outputs);
typedef struct indicator_info {
char *name;
char *full_name;
indicator_start_function start;
indicator_function indicator;
int type, inputs, options, outputs;
char *input_names[MAXINDPARAMS];
char *option_names[MAXINDPARAMS];
char *output_names[MAXINDPARAMS];
} indicator_info;
该indicator
函数通过上面的结构访问。
指标函数的给定实例如下
int add(int size,
TI_REAL const *const *inputs,
TI_REAL const *options,
TI_REAL *const *outputs);