3

When I marshal my function returning a string[] as UnmanagedType.Struct with SafeArraySubType = VarEnum.VT_ARRAY as in

namespace StackOverflow
{
  [ComVisible(true)]
  [Guid("4BDC43D4-8FD7-4F58-BEE5-E57C3C144C1B")]
  public class Array
  {
    [return: MarshalAs(UnmanagedType.Struct, SafeArraySubType = VarEnum.VT_ARRAY)]
    public string[] StringArray()
    {
      return new string[] { "foo", "bar" };
    }
  }
}

I was expecting to get a variant (UnmanagedType Enumeration)

Struct
A VARIANT, which is used to marshal managed formatted classes and value types.

However the VBScript code

WScript.Echo TypeName(CreateObject("StackOverflow.Array").StringArray)

reports String() (which is not a Variant() and therefore I will get type missmatch errors later when accesing the array).

When I change my code to either

public object[] ObjectArray()
{
  return new object[] { "foo", "bar" };
}

public object PlainObject()
{
  return new object[] { "foo", "bar" };
}

the VBScript code seems to works fine, however I would like to know why I cannot return a string[] and manually marshall it to a variant containing a safearray of variants.

It seems that the SafeArraySubType has no effect. What is my mistake?

Micha Wiedenmann
  • 19,979
  • 21
  • 92
  • 137

1 Answers1

2

Thats because the SafeArraySubType only applies to SafeArrays.

MarshalAs (UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_VARIANT)]
Alexandre Borela
  • 1,576
  • 13
  • 21
  • I find that unlikely given http://stackoverflow.com/questions/5079200/how-to-correctly-marshal-vb-script-arrays-to-and-from-a-com-component-written-in uses `UnmanagedType.Struct, SafeArraySubType = VarEnum.VT_ARRAY`. – Micha Wiedenmann Jul 17 '15 at 08:12
  • That's because the SafeArraySubType is ignored for structs. Structs by the nature are already a "variant array" (https://msdn.microsoft.com/en-us/library/vstudio/system.runtime.interopservices.unmanagedtype(v=vs.100).aspx) because they have their properties layout in sequence. – Alexandre Borela Jul 17 '15 at 10:56