0

I have a c++ function defined as

extern "C" Point* myFunc(int size) {
  Point *p = new Point[size];
  return p;
}

where point is just a struct defined as

extern "C" typedef struct _point {
  int x;
  int y;
} Point;

and inside my c# code I have

[DllImport("MyLibrary")]
static extern Point[] myFunc(int size);

and I use it as

Point[] newPoints = myFunc(3);
Debug.Log(newPoints.Length);

But the output is

33

The function is just an example, but the lenght of the array returned shouldn't be known before the function call. What is the correct way of returning an array to c# in order to use it, know its size and access it without incurring in any IndexOutOfRangeException?

  • Try declaring the array as `Point p [size] = { };`. You can also try adding the calling convention, eg. `[DllImport("MyLibrary", CallingConvention = CallingConvention.Cdecl)]`. [Here is a link for Calling Conventions](https://stackoverflow.com/questions/949862/what-are-the-different-calling-conventions-in-c-c-and-what-do-each-mean) – hijinxbassist Apr 27 '22 at 16:45
  • @hijinxbassist what if I don't know the size a priori? – VariabileAleatoria Apr 27 '22 at 17:19
  • Size is the param you had in your myFunc function. Not sure how you'd declare the array without size, except for initializing it with items. – hijinxbassist Apr 27 '22 at 18:10
  • If you don't know the size, how do you expect the marshaller to figure it out? Look at @Sunius's answer, you need to tell the marshaller how to marshal the array – Flydog57 Apr 29 '22 at 15:12

1 Answers1

1

It is impossible to determine array length from a pointer. It seems instead of throwing an exception, Unity guesses and guesses wrong. The correct way to return data in an array from C++ is to pass an array of correct size in from C#:

extern "C" void GetPoints(Point* points, int size)
{
    for (int i = 0; i < size; i++)
        points[i].x = points[i].y = i;
}

And then on C# side:

[DllImport("MyLibrary", EntryPoint = "GetPoints")]
static extern void GetPointsNative([In][Out][MarshalAs(UnmanagedType.LPArray)] Point[] points, int size);

static Point[] GetPoints(int size)
{
    var points = new Point[size];
    GetPointsNative(points, size);
    return points;
}
Sunius
  • 2,789
  • 18
  • 30