Search code examples
c#arraysobjectunmanaged

c# create unmanaged object* array


i need to create a variable length array of unmanaged object, but i need the array to be unmanaged too, so i can't use List<> or other classes but i have to malloc/realloc it in the c way.

this is my code:

unsafe class A{
    unsafe private int a1, a2;
    unsafe public byte* arr;
}

and on a different class method i would like to do something like this:

private unsafe A* arr = Marshal.AllocHGlobal(array_size * Marshal.SizeOf<A>());

Now i these questions:

  1. How to convert IntPtr to A*? OR does exist a proper c# malloc/realloc function? OR if i .dll import the real c/c++ realloc function would be safe to use it?
  2. How do i get a A* pointer to an A unmanaged object? if i try with '&' it says "cannot take the adress of [...] a managed object" but it shouldn't be managed. Am I doing something wrong in class declaration?

optional: why sizeof(A) doesn't work but Marshal.SizeOf() it's fine?


Solution

  • You cannot use C# class for such things, but you can use struct:

    [StructLayout(LayoutKind.Sequential)]
    struct A
    {
        public int A1;
        public int A2;
    }
    
    int array_size = 5;
    // just cast IntPtr to A*
    A* arr = (A*) Marshal.AllocHGlobal(array_size * Marshal.SizeOf<A>());
    // set first element of unmanaged array
    arr[0] = new A {A1 = 1, A2 = 2};
    // set second
    arr[1] = new A {A1 = 3, A2 = 4};
    
    // alternative syntax:
    // set first element
    *arr = new A { A1 = 5, A2 = 6 };
    // set second element
    *(arr + 1) = new A { A1 = 5, A2 = 6 };
    // get first element
    var first = *arr;
    var second = *(arr + 1);
    Console.WriteLine(first.A1 + " " + first.A2);
    Marshal.FreeHGlobal((IntPtr)arr);