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