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