Search code examples
c++comatlmidl

MIDL changes the Interface name


I have a COM dll , which is consumed by .NET applications using COM Inter-op. In one of the CoClasses , there is an Interface called IT6TrackData and it has one get property called TrackData

From the IDL file:

Interface IT6TrackData
{
   [propget, id(1)] HRESULT TrackData([out, retval] SAFEARRAY(BYTE) *pVal);
}

When the TLB file is viewed for the above IDL file, it shows the property as trackData ( t in lower case) For some reason the Client application were referring to this property as trackData and everything was working fine until now.

As part of enhancement the above Interface was upgraded to have a put property

Interface IT6TrackData
{
   [propget, id(1)] HRESULT TrackData([out, retval] SAFEARRAY(BYTE) *pVal);
   [propput, id(1)] HRESULT TrackData([in]SAFEARRAY(BYTE) pVal);
}

Now when the TLB file is viewed for the above IDL File, it show the property as TrackData ( t is in upper case), this is breaking the old .NET clients who continue to refer to the trackData with the “t” in lower case.

I have gone through this KB article http://support2.microsoft.com/kb/220137/en-gb

but is there a way out, does anyone know of a fix for this issue.

your attention is appreciated.

The IDL File

import "oaidl.idl";
import "ocidl.idl";

 [
   object,
   uuid(72867CE8-41B6-459E-A258-C7A162A26D5E),
   dual,
   nonextensible,
   helpstring("ITFST6TrackData Interface"),
   pointer_default(unique)
 ]
 interface ITFST6TrackData : IDispatch{
   [propget, id(1), helpstring("property TrackData")] HRESULT TrackData([out, retval]   SAFEARRAY(BYTE) *pVal);
   [propput, id(1), helpstring("property TrackData")] HRESULT TrackData([in]SAFEARRAY(BYTE) pVal);
};
[
   uuid(1D7ABC17-2738-4373-9B6B-239E344DBD21),
   version(1.0),
   helpstring("SampleCom 1.0 Type Library")
]
library SampleComLib
{
   importlib("stdole2.tlb");
   [
       uuid(2013CC98-47A7-468F-912A-2A2CAE25E327),
       helpstring("TFST6TrackData Class")
   ]
   coclass TFST6TrackData
   {
        [default] interface ITFST6TrackData;
   };
};

Solution

  • This is the side-effect of a hack in the type library generator built into Windows. It has a workaround for trouble caused by a case-insensitive language. Which might declare a type in one casing but refer to it elsewhere in another casing. Visual Basic is the prime example of such a language.

    The hack is very crude, it takes the casing of the first identifier it encounters and then changes the casing of any subsequent identifier to match. The most typical cause of an unexpected casing change is the name of a parameter, typically spelled with a lower-case first letter. So you probably had a "trackData" method parameter in a previous version of the code.

    And in your revision, either the order of the identifiers changed or you renamed or removed that parameter. Now getting "TrackData" instead.

    If you have existing client code around that depends on the original casing then there's little you can do but change the casing in your source. Fugly fix, but unsurprising to your clients since they can't tell the difference :)