4

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.

1 Answer 1

1

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;
}
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for your reply. I tried that but it still crashes. Actually I tried it with no return also, with void before posting but still it crashes.
@AliaAdly And the buffer[50]; is too much small... Just from copy-pasting the output to a notepad it is around 80 characters. Make it around 200 just to be sure and use the _snprintf that has a parameter for the length (but read the security note if you use _snprintf)
Thank you so much! It worked!! The problem was indeed in the size of the buffer!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.