0

I have written a simple cpp function to take in input parameters from swift, and use those parameters in a cpp function from a cpp library (If anybody is familiar with CPLEX, I'm basically using the CPLEX cpp library in swift. I'd like to do the preprocessing for the problem and pass those values into cpp to do the optimisation)

The simple cpp function that I wrote requires that I provide a double [][] parameter, which translates to UnsafeMutablePointer< UnsafeMutablePointer<Double>? > in swift. I have written a small piece of code to convert to that from [[Double]].

let arrayToConvert = [[3.0, 4.0], [2.0, 3.3]]

let outerArray = UnsafeMutablePointer< UnsafeMutablePointer<Double> >.allocate(capacity: arrayToConvert.count)

for idx in 0..<dists.count {
    let arrPointer = UnsafeMutablePointer<Double>.allocate(capacity: dists[idx].count)
    arrPointer.initialize(from: arrayToConvert[idx], count: arrayToConvert[idx].count)

    outerArray.advanced(by: idx).pointee = arrPointer
}

I then make a call to my small cpp function called opt(double **), using the outerArray created, but it didn't work, because the outerArray doesn't match the requirement of the small function I wrote, which takes in UnsafeMutablePointer< UnsafeMutablePointer<Double>? > (take note of the optional).

So I tried changing

let outerArray = UnsafeMutablePointer< UnsafeMutablePointer<Double> >.allocate(capacity: arrayToConvert.count)

to

let outerArray = UnsafeMutablePointer< UnsafeMutablePointer<Double>? >.allocate(capacity: arrayToConvert.count)

Things start to get weird here. When I add the optional (?), I got an error "Undefined symbol: _opt". Anybody could perhaps point me to what I'm missing or what I'm doing wrong here?

Here are the MWE codes:

main.swift

import Foundation

let arrayToConvert = [[3.0, 4.0], [2.0, 3.3]]

let outerArray = UnsafeMutablePointer< UnsafeMutablePointer<Double> >.allocate(capacity: arrayToConvert.count)

for idx in 0..<dists.count {
    let arrPointer = UnsafeMutablePointer<Double>.allocate(capacity: dists[idx].count)
    arrPointer.initialize(from: arrayToConvert[idx], count: arrayToConvert[idx].count)

    outerArray.advanced(by: idx).pointee = arrPointer
}

opt(outerArray)

cp.cpp

#include "cp.hpp"

template <size_t rows, size_t cols>
double opt(double (&array)[rows][cols]) {
    return 0.0;
}

cp.hpp

#ifndef cp_hpp
#define cp_hpp

#include <stdio.h>

#ifdef __cplusplus
extern "C" {
#endif

double opt(double **);

#ifdef __cplusplus
}
#endif

#endif

paper1-Bridging-Header.h

#ifndef paper1_Bridging_Header_h
#define paper1_Bridging_Header_h

#include "paper1/cp/cp.hpp"

#endif
Kelvin Lee
  • 39
  • 5
  • `double opt(double **` in cp.hpp looks incomplete. Is that your actual, copy/pasted code? – Martin R Oct 16 '19 at 13:41
  • And note that C++ functions are generally *not* imported into Swift: https://stackoverflow.com/q/24042774/1187415. – Martin R Oct 16 '19 at 13:41
  • @MartinR Sorry, I've made an edit. The thing is the cpp function was working fine from swift, before I added the ? in the declaration of ```outerArray```, so I'm pretty sure the cpp function was working in swift. – Kelvin Lee Oct 16 '19 at 13:54
  • I am fairly sure that this is a problem of C++ with Swift. The linker complains that there is no `_opt` symbol. – What happens if you implement a plain C function `double opt(double **array) { return 0.0; }` instead of a C++ template? – Martin R Oct 16 '19 at 14:23
  • In fact, I have tried implementing a cpp function that takes nothing at all, i.e. ```double opt() { return 0.0; }```, and I get the same problem after adding the optional ?. – Kelvin Lee Oct 16 '19 at 14:37
  • How can it have worked before adding the ?, if that does not match the function parameter? And C++ functions are name-mangled and not imported to Swift. – I suggest to start with pure C functions, defined in C files file.h and file.c. Does that work? – Martin R Oct 16 '19 at 14:42
  • I mean, the code compiled fine, and it was able to locate ```opt()``` without the ?, and yes, the ```outerArray``` isn't even used as a parameter for the ```opt``` function. As soon as I add the ?, the code breaks. – Kelvin Lee Oct 16 '19 at 14:46

0 Answers0