locked
How can you pass a zero length Array<byte> over ABI boundary?

    Question

  • How can you return a zero length byte array from C++ WinRT component, so that it is different value than nullptr?

    in C++

    Object ^Component::GetValue()

    {

       auto retVal = ref new Array<byte>(0); //Note this is not nullptr!

       return retVal;

    }

    So on C#

      var value = Component.GetValue();

    the value is null but not an empty array. How can I return an empty zero length array from C++ component, so it does not become null in managed code?

    Wednesday, April 3, 2013 1:43 PM

All replies

  • I don't think it's possible, though it seems like it might be a bug to me.

    The best workaround I can think of is to return an element count as an out parameter, e.g.:

            Platform::Array<uint8>^ Component::GetValue(int* elementCount)
            {
                if (elementCount == nullptr)
                {
                    throw ref new Platform::InvalidArgumentException();
                }
    
                // Use -1 to signal that we're returning nullptr.
                *elementCount = -1;
    
                // Do stuff where maybe we'd return nullptr
                if (SomeValue < 0)
                {
                	return nullptr;
                }
    
                // We succeeded in doing stuff so return an array of 0.
                *elementCount = 0;
                return ref new Platform::Array<uint8>(0);
            }
    

    And then on the C# side:

    int elementCount;
    var value = Component.GetValue(out elementCount);
    
    if (elementCount == 0)
    {
        value = new byte[] { };
    }
    
    That way you can distinguish between real null and empty, and even assign an empty array on the C# side if needed (as in the example above).

    XNA/DirectX MVP | Website | Blog | @mikebmcl

    Wednesday, April 3, 2013 8:27 PM
  • Actually this does not help in the context I am trying to do (need to return Object ^)

    However I tried this:

    C++

    Object^ Component::Test(Object ^value)

    {

    return value;

    }

    C#

    byte [] array = new byte[0];

    object value = Component.Test(array);

    In this instance value is correctly a byte array of zero length. So the array can be passed as return value, I just do not know how to package this on C++ RT side.

    Does anyone know?

    Thursday, April 4, 2013 10:07 AM