I am trying to understand this "IT JUST WORKS" magic for C#/C++ interop, but currently IT'S JUST A NIGHTMARE.
I am playing with Mandelbrot computations and want to offload the computing core to native C++ and SSE2. This is working, with P/Invoke. Now I want to change to IJW, to be more typesafe and because I want to understand it. But it was decades ago when I scratched at the surface of C++.
I have a struct Complex { double real; double imag; }
to hold the start values for the Mandelbrot loop, and I'd like to call a function like this:
Compute(int vectorSize, Complex[] points, double maxValue, int maxLoops, int[] result)
Now I created a CLR Class Library with VS Express 2013 and put this into a Header file:
public value struct Complex
{
double real;
double imag;
};
public ref class Computations
{
public:
static void Basic(int vectorSize, array<Complex,1>^ points, double maxRadius, int maxLoops, array<int,1>^ result);
};
class NativeComputations
{
public:
static void Basic(int vectorSize, Complex* points, double maxRadius, int maxLoops, int* result);
};
and in the CPP file this:
#pragma managed
void Mandelbrot::Computations::Basic(int vectorSize, array<Complex,1>^ points, double maxRadius, int maxLoops, array<int,1>^ result)
{
pin_ptr<Complex> pPoints = &points[0];
pin_ptr<int> pResult = &result[0];
NativeComputations::Basic(vectorSize, pPoints, maxRadius, maxLoops, pResult);
}
#pragma unmanaged
void Mandelbrot::NativeComputations::Basic(int vectorSize, Complex* points, double maxRadius, int maxLoops, int* result)
{
double foo = points[0].real;
}
At this point I am stuck - error C3821: 'points': managed type or function cannot be used in an unmanaged function
So I need to use something unmanaged. I can repeat my code and declare a ComplexNative struct (by omitting the "value" keyword). This is feasible, but repeat code? And even if this is the way, what is necessary to translate the Complex[] to a pinned ComplexNative*?
And please, I don't want to split the struct into a double[] real, double[] imag. This could lead to a simpler workaround, but I'd like to know how to do it right.