tlbimp changes from v2 I4 became VT_RECORD RRS feed

  • Question

  • I noticed that the output of tlbimp differs after version 2.0 of the framework.  In the v2.0 framework tlbimp generated this:

                MethodCodeType = MethodCodeType.Runtime)]
    public virtual void GetOptions(
           [MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR), In] 
                ref Array OptionNames, 
           [MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_I4)]
                out Array Types);

    In the 4.0 framework this is generated:

                MethodCodeType = MethodCodeType.Runtime)]
    public virtual void GetOptions(
           [MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR), In] 
               ref Array OptionNames, 
           [MarshalAs(UnmanagedType.SafeArray, SafeArraySubType  VarEnum.VT_RECORD)] 
               out Array Types);

    Note that the safearray subtype has changed from VT_I4 to VT_RECORD.  This was run against the same tlb file.  The sub-type is defined in the idl file as:


     typedef [uuid(1589F025-0488-11D3-B95F-00C0BEF81B63A),
          helpstring("The data type of an option value."),
           enum OptionServiceDataType {
              [ helpstring("  The option value is a string."),
                helpcontext(0x00864001) ]
              [ helpstring("  The option value is Boolean (true/false)."),
                helpcontext(0x00864002) ]
              [ helpstring("  The option value is an integer."),
                helpcontext(0x00864003) ]
              [ helpstring("  The option value is a real number."),
                helpcontext(0x00864004) ]
           } OptionServiceDataType;

    Does anyone know why this change was made and which definition should be considered as "technically correct"?


    Tuesday, April 4, 2017 6:30 PM

All replies

  • OleVariant::CreateSafeArrayDescriptorForArrayRef apparently recognizes VT_RECORD and calls SafeArraySetRecordInfo to store the enum type to the SAFEARRAY, using the element type of the managed array at run time so that MarshalAsAttribute.SafeArrayUserDefinedSubType is not needed. This seems reasonable but I don't believe that software communicating over COM usually requires such information, because it would be cumbersome to provide from C++.
    Tuesday, April 4, 2017 10:47 PM
  • Thank you for your reply.  I don't disagree, but it's not clear why the tlbimp tool was changed to generate VT_RECORD, rather than VT_I4 for enums.  The reason I came across this issue, is that I have C++ code that needs to return the correct SAFEARAAY subtype and there doesn't seem to be one.  All attempts to supply SafeArrayCreateEx with a correct IRecordInfo have failed with invalid parameter.  I've actually used the debugger to look thru the ITypeInfo data and I can pull the enum values out.  Since tlbimp has generated a VT_RECORD subtype, the managed code throws a safearray type mismatched error if a subtype of VT_I4 is returned.  It would work fine if tlbimp used VT_I4 as it use to. 

    There must be some reason MS made this change?


    Wednesday, April 5, 2017 2:54 PM
  • Hi Static Shock,

    Based on your description, I try to find related documents about this changing, but I could not find any documents to describe the changing. I would suggest that you could post an additional feedback on the following page.

    Best regards,

    Cole Wu

    MSDN Community Support<br/> Please remember to click &quot;Mark as Answer&quot; the responses that resolved your issue, and to click &quot;Unmark as Answer&quot; if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact <a href=""></a>.

    Tuesday, April 25, 2017 1:37 AM