Home > Software engineering >  Fixed keyword with things that can be null
Fixed keyword with things that can be null

Time:12-21

I have a native C DLL that takes lots of pointers to arrays as its parameters, along with integers to indicate the sizes of those arrays. I'm calling it from C# like this deliberately simplified illustration;

unsafe
{
    fixed (type1* thing1 = &arrayOfThing1[0])
    {
        fixed (type2* thing2 = &arrayOfThing2[0])
        {
            DllCallThatTakesLotsOfPointers(thing1, thing2);
        }
    }
}

Sometimes the arrays can be empty, in which case we just pass a null pointer as that parameter and specify zero as the size. "Just" in C at least. In C#, using this type of code, if one of the arrays is empty then the fixed block trying to get the address throws a null reference error.

It would be really nice if I could use something like

fixed (type1* thing1 = arrayOfThing1==null? 0 : &arrayOfThing1[0])

However that won't compile.

Googling has produced nothing on this. I've got things working using a horrible bodge where I have properties checking for null arrays and returning dummy arrays of all the different types, and length properties that behave deliberately wrong if they're used with the dummy arrays. It's difficult to read and maintain.

Does anyone know of a better way of dealing with this? There are many arrays which may or may not be in use, and several different function calls all along similar lines, so having a different set of nested "fixed" blocks for each combination isn't a viable option.

CodePudding user response:

As you can see in the fixed statement documentation,
you can assign the pointers (e.g. thing1) to the array itself (e.g. arrayOfThing1) instead of the address of the first element. The address will still be that of the first element as you require.

For example:

int[] arrayOfThing1 = new int[10];
unsafe
{
    fixed (int* thing1 = arrayOfThing1)
    {
        // here thing1 has valid addresses
    }
}

This automatically takes care of the null case:

int[] arrayOfThing1 = null;
unsafe
{
    fixed (int* thing1 = arrayOfThing1)
    {
        // here thing1 is 0 (NULL)
    }
}
  • Related