Include Unmanaged Type attribute in COM interface

I’m writing COM interfaces in Oxygene for a COM callable wrapper class. I can’t figure out how to marshall a System.Decimal property as currency (native COM type) since the Oxygene compiler won’t allow the syntax that worked for Delphi.NET.

Here’s a chopped down example of how I did it succesfully in Delphi.NET

[ComVisible(True)]
IVarious = interface(IInterface)
['{2DBF9ACD-1574-4BE4-812A-5D0B8E9AA025}']
  function get_MyString: String;
  procedure set_MyString(strValue: String);
  [return: MarshalAs(UnmanagedType.Currency)]
  function get_MyAmount: System.Decimal;
  procedure set_MyAmount([MarshalAs(UnmanagedType.Currency)] curValue: System.Decimal);
  property MyString: String read get_MyString write set_MyString;
  property MyAmount: System.Decimal read get_MyAmount write set_MyAmount;
end;

// In Delphi.NET the implementing class only needed to have the methods, not the properties
[ComVisible(False)]
[ClassInterface(ClassInterfaceType.None)]
TVarious = class(TObject, Various)
private
  FMyString: string;
  FMyAmount: System.Decimal;
public
  function get_MyString: String;
  procedure set_MyString(strValue: String);
  [return: MarshalAs(UnmanagedType.Currency)]
  function get_MyAmount: System.Decimal;
  procedure set_MyAmount([MarshalAs(UnmanagedType.Currency)] curValue: System.Decimal);
end;

(I won’t bother to show the TVarious getter and setter method implementations since they’re pretty obvious.)

I understand that Oxygene doesn’t require interfaces to declare getter & setter methods. It seems to me that in fact it doesn’t allow you to have getter & setter methods. So, the only way I can convert this to Oxygene (so far) is:

[ComVisible(True)]
[Guid('2DBF9ACD-1574-4BE4-812A-5D0B8E9AA025')]
IVarious = interface
  property MyString: String read write;
  property MyAmount: System.Decimal read write;
end;

[ComVisible(False)]
[ClassInterface(ClassInterfaceType.None)]
TVarious = class(IVarious)
public
  property MyString: String;
  property MyCurrency: System.Decimal;
end;

But my problem is that I have not been able to figure out how to include the [MarshalAs(UnmanagedType.Currency)] attribute into either of these declarations.

Help on how to include this COM attribute in the interface would be appreciated.

This problem could be averted if Oxygene allowed getter & setter methods in an interface definition.
Hidden getters & setters could still be generated for properties when no methods have been defined.
eg property MyInt: Integer read write; // invitation for oxygene to declare hidden methods.

But, in cases where the read & write qualifiers name the getter & settier methods, these should be allowed, and no hidden methods generated in that situation.
eg.
function get_MyInt: integer;
procedure set_MyInt( iMyInt: Integer);
property MyInt: Integer read get_MyInt write set_MyInt; // oxygen disallows !!?

As far as I can tell, Oxygene now insists on generating hidden methods even when a getter and/or setter has been explicitly declared in the read / write qualifiers, Oxygene should’ve allowed explicit getter & setter declarations for property read / write not only for backward compatibility but also so that, as needed in my case, the MarshalAs attributes could have then been included in the getter & setter method declarations.

Thanks, logged as bugs://71385

The issue is really that we need a way to assign attributes to the result type and parameter type of the method. The next build will allow like:

    [ComVisible(True)]

    [Guid('2DBF9ACD-1574-4BE4-812A-5D0B8E9AA025')]
    IVarious = interface
      property MyString: String read write;
      [result: MarshalAs(UnmanagedType.Currency),
        param: MarshalAs(UnmanagedType.Currency)]
      property MyAmount: System.Decimal read write;

    end;

bugs://71385 got closed with status fixed.