Click here to Skip to main content
15,891,253 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Hello ,
I am just reading one book on COM. About Dynamic Linking using DLL it is said that if I increase size of my class (i.e if I change layout of class) it is problematic for client and client need to recompile dlls as well.

i.e Previously my class is like,
class __declspec(dllexport) CMath {
 int someData;
};


and now it is like,


C#
class __declspec(dllexport) CMath {
 int someData;
int someMoreData; //Why problematic? 

};



Thanks and Regards.
Posted

It is bad of course and should be avoided but it is not extremely problematic. You server will work with new version of CMath and the client with the old CMath, without someMoreData. Everything else depends on what you do with this class on client and what on server. For example, it's possible that a client always gets an instance of this class constructed on the server. The extra field will be invisible to a client, that's it.

The opposite situation will cause big troubles, memory access violation exception at best. Imagine you create an instance on client and pass it to the server. In this case, an instance does not have someMoreData. The two classes are essentially different types. Now, what happens if a server works with such an instance and access non-existing field someMoreData? It will try to access memory behind the instance of this class. As I say, access violation is the best possible case. Worse, the server could access memory after the instance and damage memory of some other object. I can imagine how hard would be to find such a bug…

—SA
 
Share this answer
 
v2
I think you misunderstood the meaning of increasing the size. COM objects only consists of a set of function in a vtable. The vtable is very similar to virtual function in a cpp-class. In COM there is no object cast like in cpp. The object cast is always QueryInterface. If your interface grows up (i.e. some additional function) you MUST use a new cast (IID_MyNewClassVersion1 -> IID_MyNewClassVersion2) inside QueryInterface. To keep published interfaces consistent you can expose a new interface including the additional functions. Thats why the client that uses the interface (this can be another application) relies on the interface layout.
Perhaps imagine you have a interface with 3 functions (the IUnknown functions too) let them call:
<br />
virtual HRESULT __stdcall a() = 0;<br />
virtual HRESULT __stdcall b() = 0;<br />
virtual HRESULT __stdcall c() = 0;<br />

an older application relies on that interface layout. Sometimes later you want to increase functionality you change the layout to:
<br />
virtual HRESULT __stdcall a() = 0;<br />
virtual HRESULT __stdcall b1() = 0;<br />
virtual HRESULT __stdcall b() = 0;<br />
virtual HRESULT __stdcall c() = 0;<br />

in this case the older application will call a function that youve implememnted later (i.e. call function b() will instead call the function b1()).
Otherwise if you update the client that uses that interface it might be older interface provider will been called with a non existing function (i.e. you call c() the implementation will not exist in the older interface).
So you can expose a new interface lets say:
// interface 1 has the guid==IID_MyNewClassVersion1
// contains the functions
<br />
virtual HRESULT __stdcall a() = 0;<br />
virtual HRESULT __stdcall b() = 0;<br />
virtual HRESULT __stdcall c() = 0;<br />

// interface 2 has the guid==IID_MyNewClassVersion2
// contains the functions
<br />
virtual HRESULT __stdcall a() = 0;<br />
virtual HRESULT __stdcall b1() = 0;<br />
virtual HRESULT __stdcall b() = 0;<br />
virtual HRESULT __stdcall c() = 0;<br />

the function query interface distinquish between the different interfaces:
<br />
HRESULT QueryInterface(RIID riid,void** ppv)<br />
{<br />
  if(IID_MyNewClassVersion1) return *(MyNewClassVersion1**)ppv=this,AddRef(),S_OK;<br />
  if(IID_MyNewClassVersion2) return *(MyNewClassVersion2**)ppv=this,AddRef(),S_OK;<br />
  return E_NOINTERFACE;<br />
}<br />

Regards.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900