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?

4
  • 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 Commented Apr 27, 2022 at 16:45
  • @hijinxbassist what if I don't know the size a priori? Commented Apr 27, 2022 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. Commented Apr 27, 2022 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 Commented Apr 29, 2022 at 15:12

1 Answer 1

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

Comments

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.