0

I am trying to use C++ code in my C# application. The following structure is created:

System.Runtime.InteropServices.StructLayout(
                        System.Runtime.InteropServices.LayoutKind.Sequential)]

public struct My_FSet
{
    public int Num;
    [System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = 100)]
    public uint[] Freqs;
}

I want to use it like an array in my code, like

My_FSet FSet = new My_FSet();
FSet.Freqs[0] = 1000;
FSet.Freqs[1] = 2500;
FSet.Freqs[3] = 3200;

But I get an error:

An unhandled exception of type 'System.NullReferenceException' occurred in MyApp.exe

Additional information: Object reference not set to an instance of an object.

It seems as if the array is not properly initialized, but I cannot do that in the struct, so how can I resolve this?

Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
PeterJ
  • 364
  • 4
  • 17
  • 1
    use constructor of struct to initialize array – Ehsan Sajjad Feb 05 '16 at 12:22
  • @Ehsan Sajjad. Can you expand on that? – PeterJ Feb 05 '16 at 12:29
  • @Patrick Hoffman. I respectfully differ from the notion that this is a duplicate question. I am aware of null references and generally understand them well enough to get along. The issue here is, however, that the array is declared in the struct where I cannot initialize it. Or so it seems, because I get the error: Cannot have instance field initializers in structs when I try to do: public uint[] Freqs = new uint[100]; – PeterJ Feb 05 '16 at 12:34
  • Are you intending the array to be inline with the rest of the struct (making it (1+100) x 4 bytes long) or the array to be a separate object, with the struct containing the int field and a pointer to the array (thus only 8 or 12 bytes long)? C# only supports the latter case without some pretty egregious use of `unsafe`. – FacticiusVir Feb 05 '16 at 12:42

1 Answers1

1

The problem is the array is never instantiated, hence the NullReferenceException. Since structs are a little different than classes, you have to give the information on creation of the object instead of assigning it later on.

Like this:

public struct My_FSet
{
    public readonly int Num;
    [System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = 100)]
    public readonly uint[] Freqs;

    public My_FSet(int num, uint[] freqs)
    {
        this.Num = num;
        this.Freqs = freqs;
    }
}

Then you can supply the array in the constructor:

My_FSet f = new My_FSet(1, new uint[] { 1, 2, 3 });
Community
  • 1
  • 1
Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325