I want to pass an array of structure to c++ native plugin from C# unity script. I did as below and I can access the data but my application crashes after the c++ function is executed and I am not sure why.
C# side:
[StructLayout(LayoutKind.Sequential)]
public struct SimpleVector3
{
public float Vx, Vy, Vz, Nx, Ny, Nz;
public SimpleVector3(float x, float y, float z, float xx, float yy, float zz)
{
Vx = x;
Vy = y;
Vz = z;
Nx = xx;
Ny = yy;
Nz = zz;
}
}
[DllImport(DLL)]
public static extern int getSomeInt();
[DllImport(DLL, CallingConvention = CallingConvention.Cdecl)]
public static extern bool PopulateVerts([In] IntPtr verts, int numOfVertices);
void Start () {
Vector3 sceneOrigin = Camera.main.transform.position;
Debug.Log("SX " + sceneOrigin.x + " SY " + sceneOrigin.y + " SZ "+ sceneOrigin.z);
SimpleVector3[] trial = new SimpleVector3[2];
SimpleVector3 v2 = new SimpleVector3(sceneOrigin.x, sceneOrigin.y, sceneOrigin.z, sceneOrigin.x + 10, sceneOrigin.y + 10, sceneOrigin.z + 10);
SimpleVector3 v1 = new SimpleVector3(15,10,3,5,10,6);
trial[0] = v1;
trial[1] = v2;
testing(trial);
}
void testing(SimpleVector3[] theList)
{
Debug.Log("the number is " + getSomeInt());
GCHandle pinnedArray = GCHandle.Alloc(theList, GCHandleType.Pinned);
IntPtr ptr = pinnedArray.AddrOfPinnedObject();
// call function passing r
bool x = PopulateVerts(ptr, theList.Length);
Debug.Log("after call " + x);
pinnedArray.Free();
}
C++ side:
extern "C" EXPORT_API int getSomeInt()
{
return 42;
}
extern "C" EXPORT_API bool PopulateVerts(SimpleVector3* verts, int numofVert) {
char buffer[50];
for (int i = 0; i < numofVert; i++) {
sprintf(buffer, "x %f , y %f , z %f \n nx %f , ny %f , nz %f ", (verts->Vx),
(verts->Vy), (verts->Vz), (verts->Nx), (verts->Ny), (verts->Nz));
Debug(buffer);
if(i < (numofVert-1)){
verts++;
}
}
return true;
}
The getSomeInt() is working fine and returns the number but then when it calls PopulateVerts it displays the data then crashes.
Output:
the number is 42
(Filename: C:/buildslave/unity/build/artifacts/generated/Metro/runtime/DebugBindings.gen.cpp Line: 51)
CallBack : x 15.000000 , y 10.000000 , z 3.000000
nx 5.000000 , ny 10.000000 , nz 6.000000
(Filename: C:/buildslave/unity/build/artifacts/generated/Metro/runtime/DebugBindings.gen.cpp Line: 51)
CallBack : x -0.011494 , y 0.069487 , z 0.090230
nx 9.988506 , ny 10.069487 , nz 10.090230
(Filename: C:/buildslave/unity/build/artifacts/generated/Metro/runtime/DebugBindings.gen.cpp Line: 51)
The program '[2640] dllimporttrial.exe' has exited with code -1073740791 (0xc0000409).
This is run on HoloLens. I am not sure what am I doing wrong and where exactly is the error.
Thank you.
The problem is probably in the return type bool
... C++ bool
is 1 byte, C# bool
is 4 byte.
Try:
[DllImport(DLL, CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
public static extern bool PopulateVerts([In] IntPtr verts, int numOfVertices);
And then there is a problem with the length of buffer
:
extern "C" EXPORT_API bool PopulateVerts(SimpleVector3* verts, int numofVert) {
char buffer[250];
for (int i = 0; i < numofVert; i++) {
_snprintf(buffer, 250, "x %f , y %f , z %f \n nx %f , ny %f , nz %f ", (verts->Vx),
(verts->Vy), (verts->Vz), (verts->Nx), (verts->Ny), (verts->Nz));
// See the security note at https://msdn.microsoft.com/en-us/library/2ts7cx93(v=vs.71).aspx
buffer[sizeof(buffer) - 1] = '\0';
Debug(buffer);
if(i < (numofVert-1)){
verts++;
}
}
return true;
}
User contributions licensed under CC BY-SA 3.0