Why did I feel I needed to use this crazy variable type??

vtable ptr->innerproc

My example file structure above

main calls proc calls innerproc

Now all these proc share the same vtable.
No big deal right??? No big deal until you spend hours trying to get main.obj and proc.obj to link with the vtable AT THE SAME ADDRESS so innerproc, which has its entry point in the vtable.

It seems now matter how I publicexterndefexternify the label that defines the entry point for innerproc, the linker just cannot figure it out.

Enter the COMM variable.

The trick with the COMM variable is that it is allocated at link time. Therefore it is always in scope.

But! It is not that simple....

A COMM variable vtable will build like a stack. In other words, utterly bassackwards from what you are used too.

foo dd 0 addr+0
foo1 dd 0 addr+4
foo2 dd 0 addr+8
foo3 dd 0 addr+12

Will build just like you expect. COMM however:

COMM bar: dword addr-12
COMM bar1:dword addr-8
COMM bar2:dword addr-4
COMM bar3:dword addr+0

Utterly bassackwards.

I'll actually show you what I did because the is one additional caveat:

comm DDS_GetLOD :dword
comm DDS_SetLOD :dword
comm DDS_GetPriority :dword
comm DDS_SetPriority :dword
comm DDS_ChangeUniquenessValue:dword
comm DDS_GetUniquenessValue :dword
comm DDS_FreePrivateData :dword
comm DDS_GetPrivateData :dword
comm DDS_SetPrivateData :dword
comm DDS_SetSurfaceDesc :dword
comm DDS_PageUnlock :dword
comm DDS_PageLock :dword
comm DDS_GetDDInterface :dword
comm DDS_UpdateOverlayZOrder :dword
comm DDS_UpdateOverlayDisplay :dword
comm DDS_UpdateOverlay :dword
comm DDS_Unlock :dword
comm DDS_SetPalette :dword
comm DDS_SetOverlayPosition :dword
comm DDS_SetColorKey :dword
comm DDS_SetClipper :dword
comm DDS_Restore :dword
comm DDS_ReleaseDC :dword
comm DDS_mLock :dword
comm DDS_IsLost :dword
comm DDS_Initialize :dword
comm DDS_GetSurfaceDesc :dword
comm DDS_GetPixelFormat :dword
comm DDS_GetPalette :dword
comm DDS_GetOverlayPosition :dword
comm DDS_GetFlipStatus :dword
comm DDS_GetDC :dword
comm DDS_GetColorKey :dword
comm DDS_GetClipper :dword
comm DDS_GetCaps :dword
comm DDS_GetBltStatus :dword
comm DDS_GetAttachedSurface :dword
comm DDS_Flip :dword
comm DDS_EnumOverlayZOrders :dword
comm DDS_EnumAttachedSurfaces :dword
comm DDS_DeleteAttachedSurface :dword
comm DDS_BltFast :dword
comm DDS_BltBatch :dword
comm DDS_Blt :dword
comm DDS_AddOverlayDirtyRect :dword
comm DDS_AddAttachedSurface :dword
comm DDS_Release :dword
comm DDS_AddRef :dword
comm DDS_QueryInterface :dword
[COLOR=red]comm _DXSurfaceStart :dword[/COLOR]

A DirectDraw7Surface vtable declared backwards, because I wrote the code to populate it forward.

DDS_QueryInterface will be at the top of the stack, or the lowest address in memory. I found and additional member is neccesary after your desired stack top member, or the last(stack top) member is misaligned. So _DXSurfaceStart is just a dummy allocation to make sure DDS_QueryInterface is at DDS_AddRef-4.
If you dont care about alignment, it does not matter.

Now I need food and bed....
Posted on 2002-11-16 11:55:39 by ThoughtCriminal
COMM, COMm, COMe, come and and give me a heacace...
Posted on 2002-11-16 15:14:28 by scientica
Let your loops unroll. Let your loops unrooo o o oll!
Posted on 2002-11-16 21:52:15 by drhowarddrfine