C# call to C and pass parameter as a pointer to an array

I have a C method with the following signature:

extern __declspec(dllexport) int my_func
    (const double(*points)[3], double parameters[MAXPARS], int* numberofparameters);

This function is part of a .lib, which I'm wrapping in a DLL (CLR/CLI) written in C++, so that I can call from C#. The signature of the C++ method is similar:

int MyFunc(const double(*points)[3],
            double parameters[MAXPARS],
            int* numberofparameters)

Now my difficulty is how to call this method from C#. The problem is the first parameter, const double(*points)[3], which I don't know how to pass. My code in C# looks like:

double[,] pts = new double[1,3];
pts[0, 0] = 1.5;
pts[0, 1] = 2.5;
pts[0, 2] = 3.5;

double[] parameters = new double[4];
int nrParams;
unsafe {
    fixed (double *points = pts) {
       fixed (double* para = &parameters[0]) {
          wrapper.MyFunc(&points, para, &nrParams);
       }

    }
}

This shows the error: Argument 1: cannot convert from double** to < CppImplementationDetails >$ArrayType ....

Any help would be appreciated.

Thanks,

Greetings,

Sorin

Upvotes: 0

Views: 170

Answers (1)

PMF
PMF

Reputation: 17298

If you already have a C++/CLI wrapper, I would adjust the API there and make that one more C#-ish.

So change the C++/CLI declaration to something like:

int MyFunc(array<double>^ points,
            array<double>^ parameters);

and then do all the managed->unmanaged wrapping in that implementation.

In the end, it would look something like this:

int MyFunc(array<double>^ points,
    array<double>^ parameters)
{

    if (points->Length != 3)
    {
        throw gcnew System::ArgumentOutOfRangeException("Expecting exactly 3 points");
    }

    double *pPoints = (double*)alloca(sizeof(double) * points->Length);

    for (int i = 0; i < points->Length; i++)
    {
        pPoints[i] = points[i];
    }

    double* pParams = (double*)alloca(sizeof(double) * parameters->Length);

    for (int i = 0; i < parameters->Length; i++)
    {
        pParams[i] = parameters[i];
    }

    double(*pPoints3)[3] = (double(*)[3])pPoints;
    int numParams = parameters->Length;
    my_func(pPoints3, pParams, &numParams);
}

However, I'm completely confused on the line with the ??? as I don't exactly know what const double(*pPoints3)[3] means. An array of 3 doubles? Or an array of pointers to doubles?

Upvotes: 1

Related Questions