I am using a C++ dll into my C# project. Using pInvoke (Platform Invoke).
My C++ code returns a double***, and the C# function returns a IntPtr.
I have the dimensions of the matrix on both sides, they are just not constant.
On C# side I have:
[DllImport("mylib.dll")]
public static extern IntPtr GetMatrix(int width, int height, int depth);
And on C++ side I have:
extern "C" {
__declspec(dllexport) double*** GetMatrix(int width, int height, int depth) {
// do stuff
return matrix;
}
}
Now I need to convert this IntPtr to a double[,,], but, I have no idea how to do that.
Basicaly I need the oposite to the answer of this question.
I've never tried this with these kinds of arrays, but this first solution may work and I'm lead to believe so by this MSDN article:
(Note this only works if you can change the function definition on the C# side) In your C# function, change your IntPtr
parameter to a double[,,]
parameter and add this MarshalAs attribute to it, similar to how the above MSDN article does it.
[DllImport("FooBar.dll")]
extern void Foo([MarshalAs(UnmanagedType.LPArray, SizeConst=**YOUR ARRAY SIZE HERE**)] double[,,] bar);
This also assumes that you have a constant-sized array, and I'm not sure how this would exactly work with a 3d array, but if you'd like to investigate this type of solution further, here's the full documentation for MarshalAsAttribute.
The other solution is very similar to the opposite of that other question. You would initialize your double[,,]
to whatever size you needed, then start filling in rows with Marshal.Copy
(this overload). You could also marshal over a single double with the same function. Something like this:
double[,,] arr = new double[25, 25, 200];
int il = arr.GetLength(0), jl = arr.GetLength(1), kl = arr.GetLength(2);
IntPtr values = DllFoo();
for (int i = 0; i < il; i++)
{
for (int j = 0; j < jl; j++)
{
for (int k = 0; k < kl; k++)
{
double[] temp = new double[1];
arr[i,j,k] = Marshal.Copy(values, temp, 1, k + j * jl + k * jl * kl);
}
}
}
You can definitely squeeze a lot more performance out of that snippet, but it should still work.