skip to Main Content

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.

2

Answers


  1. 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.

    Login or Signup to reply.
  2. 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
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search