COM inheritance Q

Mike Hearn mike at navi.cx
Thu Jan 13 15:15:58 CST 2005


On Thu, 13 Jan 2005 20:33:10 +0000, Ann and Jason Edmeades wrote:
> 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'm kind of confused too but it seems you really want two interfaces
that inherit from each other here rather than having two separate
interfaces that happen to have the same name.

So, IWineD3DSurface should inherit from IWineD3DResource which in
turn should inherit from IUnknown. Then you fill out the vtable
appropriately for overrides. Isn't object orientation in C fun :)

typedef struct
{
     IWineD3DSurfaceVtbl *lpVtbl;
     DWORD refcount;
     ....
} WineD3DSurface;

static IWineD3DSurfaceVtbl SurfaceVtbl = {
     /* IUnknown methods are reimplemented per object here but you could be cleverer */
     WineD3DSurface_QueryInterface,
     WineD3DSurface_AddRef,
     WineD3DSurface_Release,

     /* Now for the Resource methods */
     WineD3DResource_XXX,
     WineD3DResource_YYY,

     /* Now for the Surface methods */
     WineD3DSurface_AAA,
     WineD3DSurface_BBB
};

static WineD3DSurface *WineD3DSurface_Create()
{
     WineD3DSurface *obj = HeapAlloc(GetProcessHeap(), 0, sizeof(WineD3DSurface));
     
     obj->lpVtbl = &SurfaceVtbl;
}


Of course for object orientation to be *useful* like that, the WineD3DResource methods
have to be able to cast the incoming object ptr to a WineD3DResource object, so 
you need to use struct inheritance like so:

struct WineD3DSurface
{
     WineD3DResource parent;   /* note the lack of an asterisk: this embeds a copy of the struct so casting works, not a pointer */

     /* add your additional fields here ... now casting a Surface to a Resource works */
}

Remember that lpVtbl can go anywhere :)

thanks -mike




More information about the wine-devel mailing list