I am trying to call a C function from Swift , but I do not know exactly how to define variables to pass parameters. This is the function declaration:
/* Function Declarations */
extern void compute_feature_set(const double input[11025],
double M_data[], int M_size[2],
double D_data[], int D_size[2],
double DD_data[],
int DD_size[2],
double VT[10], double *mp,
double r_42[42], double *fM);
The data is an array of floats. So I tried :
let s = data.compactMap{ Double($0)}
var mSize = Array<Int32>(repeating:Int32(0.0), count:2)
var dSize = Array<Int32>(repeating:Int32(0.0), count:2)
var dD_Size = Array<Int32>(repeating:Int32(0.0), count:2)
var mData = Array<Double>(repeating:0.0, count:48)
var dData = Array<Double>(repeating:0.0, count:48)
var dD_Data = Array<Double>(repeating:0.0, count:48)
var vt = Array<Double>(repeating:0.0, count:10)
var mp = Double(0.0)
var r = Array<Double>(repeating:0.0, count:42)
var fM = Double(0)
compute_feature_set(s, &cout, &mSize, &vx, &dSize, &dD_Data, &dD_Size, &vcta, &mp, &r, &fM)
When I run the code in Clion with the following function it works fine and the output matches the expected values:
static void main_compute_feature_set(void)
{
static double dv[11025];
double DD_data[48];
double D_data[48];
double M_data[48];
double r_42[42];
double VT[10];
double fM;
double mp;
int DD_size[2];
int D_size[2];
int M_size[2];
/* Initialize function 'compute_feature_set' input arguments. */
/* Initialize function input argument 'input'. */
/* Call the entry-point 'compute_feature_set'. */
argInit_11025x1_real_T(dv);
compute_feature_set(dv, M_data, M_size, D_data, D_size,
DD_data, Dd_size, VT,
&mp, r_42, &fM);
}
However, when I run my implementation in Swift, I get very different results.
CodePudding user response:
You could try passing pointers of the Arrays, rather than the Arrays directly.
Using Imported C Functions in Swift | Apple Developer Documentation
Call Functions with Pointer Parameters
Whenever possible, Swift avoids giving you direct access to pointers. When importing C function parameters, however, Swift maps pointer parameters to standard library pointer types.
The following tables use Type as a placeholder type name to indicate syntax for the mappings.For return types, variables, and arguments, the following mappings apply:
C Syntax Swift Syntax const Type *
UnsafePointer<Type>
Type *
UnsafeMutablePointer<Type>
double[]
is pretty much equivalent to double *
in this case.
CodePudding user response:
Looks like the problem with your code is passing data to your function. You use compactMap
to make an Array
of Double
and then pass the pointer of this array. But Array
and Double
are struct
in Swift so you pass the pointer of struct with structs instead of array of double
values.
To convert your data to array of bytes you should use withUnsafeBytes
e.g.:
Swift:
let data = Data([0xaa, 0xbb, 0xcc, 0xdd])
data.withUnsafeBytes {
passData($0)
}
C/ObjC:
void passData(const double input[11025]) {
NSLog(@"%x", input[0]); // Prints: ddccbbaa
}