TrtnJohn

When exposing VB.NET classes to COM, properties that have both a getter and setter method are not consistently generated in the same order. The order of the getter and setter method in the Type Library is random and can vary between successive builds. (setter first then getter or vice versa). This is causing problems with clients that use C++ and rely on the vTable order of the methods. Is this a known bug or is there any workaround

I noticed that using C# you can specify getters and setters. But, you cannot specify parameters with properties. So, it is not possible, without changing the interfaces of the classes, to convert them to C#. (I do have a lot of properties with parameters).

Since I can't use C# the only solution I have so far is to de-compile the assembly, write a program to edit the IL to make it consistent, and then recompile the IL back into the assembly. This is a very unattractive option. Is there any other possibilities Help!



Re: Common Language Runtime COM Interop issue with VB.NET properties

Ladi Prosek - MSFT

> I noticed that using C# you can specify getters and setters.

Not sure if I understand correctly, but you can definitely specify getters and setters using VB.NET.

' Define the property.
Public Property prop1() As String
Get
' The Get property procedure is called when the value
' of a property is retrieved.
Return propertyValue
End Get
Set(ByVal value As String)
' The Set property procedure is called when the value
' of a property is modified. The value to be assigned
' is passed in the argument to Set.
propertyValue = value
End Set
End Property

It seems that in metadata order the getter is always placed before the setter. Can you post an example code which generates inconsistently ordered metadata What version of VB.NET are you using




Re: Common Language Runtime COM Interop issue with VB.NET properties

TrtnJohn

I wish I could give you a simple example. But, the problem occurs randomly. I don't want to post all of my classes that exhibit the problem because of the size. But, here is an excerpt of one:

Code Snippet

Imports System.Runtime.InteropServices

<GuidAttribute("0924A2FB-99E9-34AA-8396-14DE81BCA184")> _
Public Enum ToggleSettings As Byte
NotToggling = 0
TogglingSlow = 1
TogglingMedium = 2
TogglingFast = 3
End Enum


#Region "Interface Spec"
<GuidAttribute("4896a5b2-4ada-485c-94a3-63cd32fd300e"), _
InterfaceTypeAttribute(ComInterfaceType.InterfaceIsDual)> _
Public Interface IOutputPort
<DispId(1)> Property TogglePort() As ToggleSettings
<DispId(2)> Property PortValue() As Boolean
End Interface
#End Region

<Guid("01fc0aad-dee1-40e4-a4c2-9339627d6c78"), ClassInterface(ClassInterfaceType.None)> _
Public Class OutputPort
Implements IOutputPort

Private mPortValue As Boolean
Public Property PortValue() As Boolean Implements IOutputPort.PortValue
Get
Return mPortValue
End Get
Set(ByVal Value As Boolean)
mPortValue = Value
End Set
End Property

Private mTogglePort As ToggleSettings = ToggleSettings.NotToggling
Public Property TogglePort() As ToggleSettings Implements IOutputPort.TogglePort
Get
Return mTogglePort
End Get
Set(ByVal Value As ToggleSettings)
mTogglePort = Value
End Set
End Property
End Class ' OutputPort

When built in my assembly with a large number of other classes, Regasm generated the following typelib information for this class:

Code Snippet

typedef [uuid(0924A2FB-99E9-34AA-8396-14DE81BCA184), version(1.0) ,

custom({0F21F359-AB84-41E8-9A78-36D110E6D2F9}, "ToggleSettings")

]

enum {

ToggleSettings_NotToggling = 0,

ToggleSettings_TogglingSlow = 1,

ToggleSettings_TogglingMedium = 2,

ToggleSettings_TogglingFast = 3

} ToggleSettings;

[

odl,

uuid(4896A5B2-4ADA-485C-94A3-63CD32FD300E),

version(1.0),

dual,

oleautomation,

custom({0F21F359-AB84-41E8-9A78-36D110E6D2F9}, "IOutputPort")

]

interface IOutputPort : IDispatch {

[id(0x00000001), propget]

HRESULT PortValue([out, retval] VARIANT_BOOL* pRetVal);

[id(0x00000001), propput]

HRESULT PortValue([in] VARIANT_BOOL pRetVal);

[id(0x00000002), propput]

HRESULT TogglePort([in] unsigned char pRetVal);

[id(0x00000002), propget]

HRESULT TogglePort([out, retval] unsigned char* pRetVal);

};

[

uuid(01FC0AAD-DEE1-40E4-A4C2-9339627D6C78),

version(1.0),

noncreatable,

custom({0F21F359-AB84-41E8-9A78-36D110E6D2F9}, "OutputPort")

]

coclass OutputPort {

interface _Object;

interface IPort;

[default] interface IOutputPort;

};

Notice that the IDL has the setter first for the property TogglePort.

Here is the sticky part: I cannot reliably reproduce this problem using the full assembly. It appears to randomly generate the swapped getters and setters on random members. This class will likely generate the getters and setters correctly next time I build it with the full assembly. And, I tried just compiling this class in it's own assembly 20 or 30 times and could not reproduce the same IDL as I posted. (The getters and setters are always in the right order).





Re: Common Language Runtime COM Interop issue with VB.NET properties

Ladi Prosek - MSFT

Can you please open the assembly with ILDasm and see whether the order in metadata (i.e. the order in which ILDasm displays it) corresponds to the IDL This should help determine if this is a problem in tlbexp/regasm or in the VB compiler. Thanks!




Re: Common Language Runtime COM Interop issue with VB.NET properties

TrtnJohn

I think this is the part of the IL you are asking for:

Code Snippet

.class /*020001BC*/ interface public abstract auto ansi IOutputPort

{

.custom /*0C0001A4:0A000023*/ instance void [mscorlib/*23000001*/]System.Runtime.InteropServices.InterfaceTypeAttribute/*0100002B*/::.ctor(valuetype [mscorlib/*23000001*/]System.Runtime.InteropServices.ComInterfaceType/*0100002A*/) /* 0A000023 */ = ( 01 00 00 00 00 00 00 00 )

.custom /*0C0001A5:0A000009*/ instance void [mscorlib/*23000001*/]System.Runtime.InteropServices.GuidAttribute/*01000009*/::.ctor(string) /* 0A000009 */ = ( 01 00 24 34 38 39 36 61 35 62 32 2D 34 61 64 61 // ..$4896a5b2-4ada

2D 34 38 35 63 2D 39 34 61 33 2D 36 33 63 64 33 // -485c-94a3-63cd3

32 66 64 33 30 30 65 00 00 ) // 2fd300e..

.method /*0600089C*/ public newslot specialname abstract strict virtual

instance bool get_PortValue() cil managed

// SIG: 20 00 02

{

// Method begins at RVA 0x0

} // end of method IOutputPort::get_PortValue

.method /*0600089D*/ public newslot specialname abstract strict virtual

instance void set_PortValue(bool Value) cil managed

// SIG: 20 01 01 02

{

// Method begins at RVA 0x0

} // end of method IOutputPort::set_PortValue

.method /*0600089E*/ public newslot specialname abstract strict virtual

instance void set_TogglePort(valuetype ToggleSettings/*020001BB*/ Value) cil managed

// SIG: 20 01 01 11 86 EC

{

// Method begins at RVA 0x0

} // end of method IOutputPort::set_TogglePort

.method /*0600089F*/ public newslot specialname abstract strict virtual

instance valuetype ToggleSettings/*020001BB*/

get_TogglePort() cil managed

// SIG: 20 00 11 86 EC

{

// Method begins at RVA 0x0

} // end of method IOutputPort::get_TogglePort





Re: Common Language Runtime COM Interop issue with VB.NET properties

Ladi Prosek - MSFT

This looks like a VB bug. The best thing to do now is probably open a new bug at https://connect.microsoft.com/VisualStudio against VB. I'll make sure that it gets appropriate attention. Thanks!




Re: Common Language Runtime COM Interop issue with VB.NET properties

TrtnJohn

I added issue #298937 Thanks for spending the time to look into this.





Re: Common Language Runtime COM Interop issue with VB.NET properties

Feng Chen - MSFT

Hi TrtnJohn,

Thanks for your valuable feedback, our developer are currently investigating them now. Moreover, other community members having similar questions can check out here for more details:

https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx FeedbackID=298937&wa=wsignin1.0

Thanks!






Re: Common Language Runtime COM Interop issue with VB.NET properties

Ladi Prosek - MSFT

Actually FeedbackID 298937 was opened by TrtnJohn

I routed it directly to the VB team.





Re: Common Language Runtime COM Interop issue with VB.NET properties

TrtnJohn

Thanks Ladi! We are proceeding with our de-compile, edit IL, re-compile strategy for now. If you hear of any workarounds that aren't so drastic let me know. Thanks again,

John





Re: Common Language Runtime COM Interop issue with VB.NET properties

TrtnJohn

The end result on this issue is that it is a know problem with VS 2003 and is fixed in VS2005 SP1. The only workaround with VS 2003 is to edit the IL as noted above.