I am trying to marshal a structure from managed code to unmanaged, perform operations on it in C++ and return the result back by out parameter.
The structure has a double array and an int array (it’s just a Mesh-structure with two arrays of double and int). This approach worked fine when it was a dll for net.core and C++, but when I moved the MyMesh.cs structure from the net.core application to the unity project, I get the following error when marshaling.
Structure field of type Double[] can't be marshalled as LPArray
What is the best way to transfer a structure to a C++ DLL, perform operations on it in C++ code, and screw the new structure into the managed code in the Unity script?
The code that I use in C# and C++ is below:
MyMesh.cs
public enum BooleanType
{
Union,
Inter,
Dif
}
public struct MyMesh
{
private IntPtr floatsPtr;
private IntPtr indexesPtr;
private int floatsLength;
private int indexesLength;
[NonSerialized]
private double[] floats;
[NonSerialized]
private int[] indexes;
public MyMesh(double[] floats, int[] indexes)
{
this.floats = floats;
floatsLength = floats.Length;
floatsPtr = Marshal.AllocHGlobal(floatsLength * sizeof(double));
Marshal.Copy(floats, 0, floatsPtr, floatsLength);
this.indexes = indexes;
indexesLength = indexes.Length;
indexesPtr = Marshal.AllocHGlobal(indexesLength * sizeof(int));
Marshal.Copy(indexes, 0, indexesPtr, indexesLength);
}
private void LoadAndClear()
{
floats = new double[floatsLength];
Marshal.Copy(floatsPtr, floats, 0, floatsLength);
indexes = new int[indexesLength];
Marshal.Copy(indexesPtr, indexes, 0, indexesLength);
ClearMyMeshExtern(this);
floatsPtr = IntPtr.Zero;
indexesPtr = IntPtr.Zero;
}
private void ClearLocal()
{
Marshal.FreeHGlobal(floatsPtr);
Marshal.FreeHGlobal(indexesPtr);
}
public static bool Load(string path, out MyMesh myMesh)
{
LoadExtern(path, out myMesh);
myMesh.LoadAndClear();
return true;
}
[DllImport(pathDll, CallingConvention = CallingConvention.Cdecl)]
private static extern void ClearMyMeshExtern(MyMesh input);
[DllImport(pathDll, CallingConvention = CallingConvention.Cdecl)]
private static extern int LoadExtern(string path, out MyMesh output);
private const string pathDll = "MyMeshNative.dll";
}
And Unmanaged-part:
MyMesh.h
#pragma once
struct MyMesh {
double* floatsPtr;
int* indexesPtr;
int floatsLength;
int indexesLength;
};
MyMesh.cpp
__declspec(dllexport) int LoadExtern(const char* path, MyMesh* output) {
Mesh mesh;
LoadMesh(path, mesh);
ConvertToMyMesh(mesh, output);
return 0;
}
Thanks in advance to everyone who can help!