Привет, я пытаюсь обернуть C API с помощью Swift 4.
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>>
?
в соответствии с документами здесь Вызов функций с параметрами указателя Я должен быть в состоянии сделать это с неявным соединением, но, похоже, нет, возможно, мне следует просто создать типы указателей, а не пытаться преобразовать их из 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);
indicator
не является функцией, которую вы вызываете. Это тип (сигнатура) функции, которую вы передаете. Покажите C API, где мы на самом деле должны его передать. - person matt   schedule 20.12.2018public func indicator_abs(_ size: Int32, _ inputs: UnsafePointer<UnsafePointer<Double>?>!, _ options: UnsafePointer<Double>!, _ outputs: UnsafePointer<UnsafeMutablePointer<Double>?>!) -> Int32
. Я отредактировал вопрос. - person lbdl   schedule 20.12.2018