COM inheritance Q

Robert Shearman rob at codeweavers.com
Thu Jan 13 15:15:43 CST 2005


Ann and Jason Edmeades wrote:

>>>I have code which looks like:
>>>
>>>HRESULT WINAPI IWineD3DSurfaceImpl_GetParent(IWineD3DSurface *iface,
>>>IUnknown **pParent) {
>>>   return IWineD3DResource_GetParent((IWineD3DResource *)iface, pParent);
>>>}
>>>
>>>IWineD3DResource_GetParent is a macro:
>>>#define IWineD3DSurface_GetParent(p,a)
>>>(p)->lpVtbl->GetParent(p,a)
>>>
>>>So we then go iface->lpVtbl->GetTable. Since iface is a surface, once cast
>>>to a resource its GetParent is in the same place in the table... Hence the
>>>call ends up being effectively
>>>
>>>HRESULT WINAPI IWineD3DSurfaceImpl_GetParent(IWineD3DSurface *iface,
>>>IUnknown **pParent) {
>>>   return IWineD3DSurfaceImpl_GetParent (iface, pParent);
>>>}
>>>
>>>Whats the solution?
>>>
>>>In d3d8 I would have coded IWineD3DSurfaceImpl_GetParent as
>>>IWineD3DResourceImpl_GetParent(iface, pParent) because the Impl versions
>>>were prototyped - Is this the only way to solve this?
>>> 
>>>
>>>      
>>>
>
>  
>
>>I don't think I've got enough information to answer you correctly. Is 
>>this a multiple inheritance problem? I.e. does the object implement both 
>>IWineD3DSurface and IWineD3DResource and not have one directly 
>>inheriting from the other?
>>    
>>
>
>No, a single inheritance issue. Let me try to explain...
>
>Resource is defined as having functions A,B,C and its vtbl is {a,b,c}
>Surface is defined as having functions A,B,C,D,E,F and its vtbl is
>{a,b,c,d,e,f}. Note 'a' is an entrypoint to surface not resource, since that
>wasn't possible (see another thread a long time ago!)...
>
>So in surface_A I want to call resource_a, and code it as expected, ie
>Resource_a((resource) iface, parms)... But the entrypoint, regardless of the
>casting, is got from the first entry in the vtbl, which (again, regardless
>of the casting) is surfaces a function...
>
>Better?
>  
>

In that case, yes, you will have to add a prototype for the base 
implementation and call it from the inheriting object. You have to tell 
the compiler where the implementation is somewhere along the line, but 
putting the base implementation directly into the vtable will result in 
conflicting types, so adding a new function for the inheriting object is 
the best way to do it.
This would be slightly easier in C++.

Rob



More information about the wine-devel mailing list