1

Context:

I'm trying to use a few COM Interface (Direct2D 1.1) from a Delphi application. For that purpose, I have to port the interfaces to Delphi. I have done that but I have a problem with one of the interfaces: the method I call is not the correct one. I verified that by writing the exact same piece of code in C++ and in Delphi. Running both under the debugger, I see that the code called by Delphi is not the same as the code called by C++. So I made a mistake in porting that interface.

To find out where my error is, I have the idea to dump all method pointers to compare the address shown by C++ and by Delphi. They should be the same as the point to the same DLL.

I don't know how to get hand on the VMT! I have read this but it is not applicable in my case: the .h file do not contain the C equivalent.

I'm looking for something similar to offsetof() and sizeof() that I use to check structures. And something to get the address of a given interface method.

Any help appreciated. PS: I hope that my English is understandable.

fpiette
  • 11,983
  • 1
  • 24
  • 46
  • It would be more useful to show your Delphi code and the original COM declaration of the interface so that someone can point out what you did wrong with the translation. – Remy Lebeau Aug 23 '20 at 00:39
  • Delphi code is hundreds or thousands of lines. Actually there is interface inheritance: ID2D1DeviceContext inherit from ID2D1RenderTarget which inherit from ID2D1Resource which inherit from IUnknown. Those are in d2d1_1.h and d2d1.h (You have in in Win SDK). – fpiette Aug 23 '20 at 05:28
  • The problem is not in the functions itself (CreateBitmapFromDxgiSurface), I checked that the calling sequence is the same and that the correct parameters are passed onto the stack. Since the API is very large, I probably made error elsewhere as well. That why I'm looking for a way to peek at VMT. I do similar thing with struct using sizeof() and offsetof(). I'm really looking for the equivalent for interfaces. That is the object of my SO question. – fpiette Aug 23 '20 at 05:28
  • And by the way, as you probably know; d2d1.h is already translated to Delphi by Embarcadero. The more recent files are not. – fpiette Aug 23 '20 at 05:35
  • I saved the interface code there: http://www.overbyte.eu/arch/dump/ID2D1DeviceContext.pas – fpiette Aug 23 '20 at 05:44
  • I don't know about delphi but for example, why do you have the two CreateBitmap methods one after the other? In C#, you would have the first interface's methods, then the second's, etc. e.g: https://github.com/smourier/DirectN/blob/master/DirectN/DirectN/Generated/ID2D1DeviceContext.cs – Simon Mourier Aug 23 '20 at 06:23
  • @simon FYI: This is not Delphi stuff, it is Microsoft C++ stuff. The two CreateBitmap methods are overloaded: they don't use same argument types. – fpiette Aug 23 '20 at 10:06
  • COM is 99.9% language agnostic, not specifically related to C++, although most Microsoft tooling centers around it. There's no notion of overloading in COM, it's only about matching binary layouts. You must declare something that's 1-1 equivalent to binary layout. Binary layout of ID2D1DeviceContext is certainly not the two CreateBitmap methods asides. It much resembles to what I point in C# (it's just missing the 3 IUnknown methods which are implicit in C# when doing interop); I guess in Delphi you must also declare some binary order somewhere. – Simon Mourier Aug 23 '20 at 10:38
  • @SimonMourier With the answer to my question I gave below, I will now be able to compare with my Delphi translation (At run time). All addresses must be the same in Delphi since they are located in the same DLL.I will see what to do with overloaded methods. I will add a comment later with my findings. – fpiette Aug 23 '20 at 13:55
  • @SimonMourier That was it: the overloaded functions introduced in C++ by the keyword "using" must be ignored when porting to Delphi. Delphi compiler does what it needs to call it from inherited interface. – fpiette Aug 23 '20 at 14:21

1 Answers1

1

I found the solution, so I will answer my own question:

Below is the code required to load the VMT of interface whose pointer is variable "Screen" into array of pointers VMT. The code assume there are 93 methods (That is actually the case). I have yet to know how to get the count of methods in a given interface to fully automate the process.

UINT_PTR* Ptr1 = reinterpret_cast<UINT_PTR*>(Screen);
UINT_PTR* Ptr2 = reinterpret_cast<UINT_PTR*>(*Ptr1);
UINT_PTR* VMT[92];
for (UINT I = 0; I < ARRAYSIZE(VMT); I++) {
    VMT[I] = reinterpret_cast<UINT_PTR*>(*Ptr2);
    Ptr2++;
}

I verifyed that this code is OK by using the debugger and loading Windows symbols. This gives the following result in VMT:

+       [0] 0x6dd34e90 {d2d1.dll!ComObjectImpl<class RefCountedObject<class D2DDeviceContext,struct LockingRequired,struct LockFactoryOnReferenceReachedZero>,class type_list<struct ID2D1DeviceContext6,class type_list<struct ID2D1DeviceContext5,class type_list<struct ID2D1DeviceContext4,class type_list<struct ID2D1DeviceContext3,class type_list<struct ID2D1DeviceContext2,class type_list<struct ID2D1DeviceContext1,class type_list<struct ID2D1DeviceContext,class type_list<class IRenderTargetInternal,class type_list<struct ID2D1GdiInteropRenderTarget,class type_list<struct ID2D1ImagingDeviceContext,class type_list<struct ID2D1PrivateCompositorDeviceContext,class type_list<struct ID2D1PrivatePencilDeviceContext,class type_list<struct ID2D1PrivateTestDeviceContext,class type_list<struct ID2D1PrivateInkingDeviceContext,class type_list<struct CompoundCast<struct ID2D1RenderTarget,struct ID2D1DeviceContext6>,class type_list<struct CompoundCast<struct ID2D1Resource,struct ID2D1DeviceContext6>,class null_type> > > > > > > > > > > > > > > > >::QueryInterface(struct _GUID const &,void * *)} {...}    unsigned int *
+       [1] 0x6dd208e0 {d2d1.dll!RefCountedObject<class D2DDeviceContext,struct LockingRequired,struct LockFactoryOnReferenceReachedZero>::AddRef(void)} {...}  unsigned int *
+       [2] 0x6dcfc150 {d2d1.dll!RefCountedObject<class D2DDeviceContext,struct LockingRequired,struct LockFactoryOnReferenceReachedZero>::Release(void)} {...} unsigned int *
+       [3] 0x6dda0aa0 {d2d1.dll!D2DDeviceContextBase<struct ID2D1BitmapRenderTarget,struct ID2D1BitmapRenderTarget,struct ID2D1DeviceContext6>::GetFactory(struct ID2D1Factory * *)const } {...}   unsigned int *
+       [4] 0x6dd99f40 {d2d1.dll!D2DDeviceContextBase<struct ID2D1BitmapRenderTarget,struct ID2D1BitmapRenderTarget,struct ID2D1DeviceContext6>::CreateBitmap(struct D2D_SIZE_U,void const *,unsigned int,struct D2D1_BITMAP_PROPERTIES const *,struct ID2D1Bitmap * *)} {...}  unsigned int *
+       [5] 0x6dd29d40 {d2d1.dll!D2DDeviceContextBase<...>::CreateBitmapFromWicBitmap(void)} {2337640550}   unsigned int *
+       [6] 0x6dd9cce0 {d2d1.dll!D2DDeviceContextBase<struct ID2D1BitmapRenderTarget,struct ID2D1BitmapRenderTarget,struct ID2D1DeviceContext6>::CreateSharedBitmap(struct _GUID const &,void *,struct D2D1_BITMAP_PROPERTIES const *,struct ID2D1Bitmap * *)} {...}    unsigned int *
+       [7] 0x6dc75440 {d2d1.dll!D2DDeviceContextBase<struct ID2D1BitmapRenderTarget,struct ID2D1BitmapRenderTarget,struct ID2D1DeviceContext6>::CreateBitmapBrush(struct ID2D1Bitmap *,struct D2D1_BITMAP_BRUSH_PROPERTIES const *,struct D2D1_BRUSH_PROPERTIES const *,struct ID2D1BitmapBrush * *)} {...}    unsigned int *
+       [8] 0x6dcfe940 {d2d1.dll!D2DDeviceContextBase<struct ID2D1BitmapRenderTarget,struct ID2D1BitmapRenderTarget,struct ID2D1DeviceContext6>::CreateSolidColorBrush(struct _D3DCOLORVALUE const *,struct D2D1_BRUSH_PROPERTIES const *,struct ID2D1SolidColorBrush * *)} {...}   unsigned int *
+       [9] 0x6dd9b7a0 {d2d1.dll!D2DDeviceContextBase<struct ID2D1BitmapRenderTarget,struct ID2D1BitmapRenderTarget,struct ID2D1DeviceContext6>::CreateGradientStopCollection(struct D2D1_GRADIENT_STOP const *,unsigned int,enum D2D1_GAMMA,enum D2D1_EXTEND_MODE,struct ID2D1GradientStopCollection * *)} {...}   unsigned int *
+       [10]    0x6dd9c490 {d2d1.dll!D2DDeviceContextBase<struct ID2D1BitmapRenderTarget,struct ID2D1BitmapRenderTarget,struct ID2D1DeviceContext6>::CreateLinearGradientBrush(struct D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES const *,struct D2D1_BRUSH_PROPERTIES const *,struct ID2D1GradientStopCollection *,struct ID2D1LinearGradientBrush * *)} {...}   unsigned int *
+       [11]    0x6dd9ca10 {d2d1.dll!D2DDeviceContextBase<struct ID2D1BitmapRenderTarget,struct ID2D1BitmapRenderTarget,struct ID2D1DeviceContext6>::CreateRadialGradientBrush(struct D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES const *,struct D2D1_BRUSH_PROPERTIES const *,struct ID2D1GradientStopCollection *,struct ID2D1RadialGradientBrush * *)} {...}   unsigned int *
+       [12]    0x6dd9aec0 {d2d1.dll!D2DDeviceContextBase<struct ID2D1BitmapRenderTarget,struct ID2D1BitmapRenderTarget,struct ID2D1DeviceContext6>::CreateCompatibleRenderTarget(struct D2D_SIZE_F const *,struct D2D_SIZE_U const *,struct D2D1_PIXEL_FORMAT const *,enum D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS,struct ID2D1BitmapRenderTarget * *)} {...}    unsigned int *
+       [13]    0x6dd9c330 {d2d1.dll!D2DDeviceContextBase<struct ID2D1BitmapRenderTarget,struct ID2D1BitmapRenderTarget,struct ID2D1DeviceContext6>::CreateLayer(struct D2D_SIZE_F const *,struct ID2D1Layer * *)} {...}    unsigned int *
+       [14]    0x6dd9c6c0 {d2d1.dll!D2DDeviceContextBase<struct ID2D1BitmapRenderTarget,struct ID2D1BitmapRenderTarget,struct ID2D1DeviceContext6>::CreateMesh(struct ID2D1Mesh * *)} {...}    unsigned int *
+       [15]    0x6dd9e5e0 {d2d1.dll!D2DDeviceContextBase<struct ID2D1BitmapRenderTarget,struct ID2D1BitmapRenderTarget,struct ID2D1DeviceContext6>::DrawLine(struct D2D_POINT_2F,struct D2D_POINT_2F,struct ID2D1Brush *,float,struct ID2D1StrokeStyle *)} {...}   unsigned int *
+       [16]    0x6dd158b0 {d2d1.dll!D2DDeviceContextBase<...>::DrawRectangle(void)} {2337640550}   unsigned int *
+       [17]    0x6dd12700 {d2d1.dll!D2DDeviceContextBase<...>::FillRectangle(void)} {2337640550}   unsigned int *
+       [18]    0x6dd9e920 {d2d1.dll!D2DDeviceContextBase<struct ID2D1BitmapRenderTarget,struct ID2D1BitmapRenderTarget,struct ID2D1DeviceContext6>::DrawRoundedRectangle(struct D2D1_ROUNDED_RECT const *,struct ID2D1Brush *,float,struct ID2D1StrokeStyle *)} {...}  unsigned int *
+       [19]    0x6dd9fa50 {d2d1.dll!D2DDeviceContextBase<struct ID2D1BitmapRenderTarget,struct ID2D1BitmapRenderTarget,struct ID2D1DeviceContext6>::FillRoundedRectangle(struct D2D1_ROUNDED_RECT const *,struct ID2D1Brush *)} {...}  unsigned int *
+       [20]    0x6dd9db00 {d2d1.dll!D2DDeviceContextBase<struct ID2D1BitmapRenderTarget,struct ID2D1BitmapRenderTarget,struct ID2D1DeviceContext6>::DrawEllipse(struct D2D1_ELLIPSE const *,struct ID2D1Brush *,float,struct ID2D1StrokeStyle *)} {...}    unsigned int *
+       [21]    0x6dd9f3d0 {d2d1.dll!D2DDeviceContextBase<struct ID2D1BitmapRenderTarget,struct ID2D1BitmapRenderTarget,struct ID2D1DeviceContext6>::FillEllipse(struct D2D1_ELLIPSE const *,struct ID2D1Brush *)} {...}    unsigned int *
+       [22]    0x6dcd8c00 {d2d1.dll!D2DDeviceContextBase<...>::DrawGeometry(void)} {2337640550}    unsigned int *
+       [23]    0x6dcd1660 {d2d1.dll!D2DDeviceContextBase<...>::FillGeometry(void)} {2337640550}    unsigned int *
+       [24]    0x6dd9f5f0 {d2d1.dll!D2DDeviceContextBase<struct ID2D1BitmapRenderTarget,struct ID2D1BitmapRenderTarget,struct ID2D1DeviceContext6>::FillMesh(struct ID2D1Mesh *,struct ID2D1Brush *)} {...}    unsigned int *
+       [25]    0x6dd9f800 {d2d1.dll!D2DDeviceContextBase<struct ID2D1BitmapRenderTarget,struct ID2D1BitmapRenderTarget,struct ID2D1DeviceContext6>::FillOpacityMask(struct ID2D1Bitmap *,struct ID2D1Brush *,enum D2D1_OPACITY_MASK_CONTENT,struct D2D_RECT_F const *,struct D2D_RECT_F const *)} {...}    unsigned int *
+       [26]    0x6dd12080 {d2d1.dll!D2DDeviceContextBase<...>::DrawBitmap(void)} {2337640550}  unsigned int *
+       [27]    0x6dcfafb0 {d2d1.dll!D2DDeviceContextBase<...>::DrawTextW(void)} {2337640550}   unsigned int *
+       [28]    0x6dd9ef40 {d2d1.dll!D2DDeviceContextBase<struct ID2D1BitmapRenderTarget,struct ID2D1BitmapRenderTarget,struct ID2D1DeviceContext6>::DrawTextLayout(struct D2D_POINT_2F,struct IDWriteTextLayout *,struct ID2D1Brush *,enum D2D1_DRAW_TEXT_OPTIONS)} {...}  unsigned int *
+       [29]    0x6dc807c0 {d2d1.dll!D2DDeviceContextBase<...>::DrawGlyphRun(void)} {2337640550}    unsigned int *
+       [30]    0x6dc7f650 {d2d1.dll!D2DDeviceContextBase<struct ID2D1BitmapRenderTarget,struct ID2D1BitmapRenderTarget,struct ID2D1DeviceContext6>::SetTransform(struct D2D_MATRIX_3X2_F const *)} {...}   unsigned int *
+       [31]    0x6dcfbe30 {d2d1.dll!D2DDeviceContextBase<struct ID2D1BitmapRenderTarget,struct ID2D1BitmapRenderTarget,struct ID2D1DeviceContext6>::GetTransform(struct D2D_MATRIX_3X2_F *)const } {...}   unsigned int *
+       [32]    0x6dcfcbb0 {d2d1.dll!D2DDeviceContextBase<...>::SetAntialiasMode(void)} {2337640550}    unsigned int *
+       [33]    0x6dcfcd70 {d2d1.dll!D2DDeviceContextBase<struct ID2D1BitmapRenderTarget,struct ID2D1BitmapRenderTarget,struct ID2D1DeviceContext6>::GetAntialiasMode(void)const } {...}    unsigned int *
+       [34]    0x6dda3cf0 {d2d1.dll!D2DDeviceContextBase<struct ID2D1BitmapRenderTarget,struct ID2D1BitmapRenderTarget,struct ID2D1DeviceContext6>::SetTextAntialiasMode(enum D2D1_TEXT_ANTIALIAS_MODE)} {...} unsigned int *
+       [35]    0x6dcfcf00 {d2d1.dll!D2DDeviceContextBase<struct ID2D1BitmapRenderTarget,struct ID2D1BitmapRenderTarget,struct ID2D1DeviceContext6>::GetTextAntialiasMode(void)const } {...}    unsigned int *
+       [36]    0x6dcfd870 {d2d1.dll!D2DDeviceContextBase<...>::SetTextRenderingParams(void)} {2337640550}  unsigned int *
+       [37]    0x6dda1b40 {d2d1.dll!D2DDeviceContextBase<struct ID2D1BitmapRenderTarget,struct ID2D1BitmapRenderTarget,struct ID2D1DeviceContext6>::GetTextRenderingParams(struct IDWriteRenderingParams * *)const } {...} unsigned int *
+       [38]    0x6dda3a90 {d2d1.dll!D2DDeviceContextBase<struct ID2D1BitmapRenderTarget,struct ID2D1BitmapRenderTarget,struct ID2D1DeviceContext6>::SetTags(unsigned __int64,unsigned __int64)} {...}  unsigned int *
+       [39]    0x6dda1a40 {d2d1.dll!D2DDeviceContextBase<struct ID2D1BitmapRenderTarget,struct ID2D1BitmapRenderTarget,struct ID2D1DeviceContext6>::GetTags(unsigned __int64 *,unsigned __int64 *)const } {...}    unsigned int *
+       [40]    0x6dda2ac0 {d2d1.dll!D2DDeviceContextBase<struct ID2D1BitmapRenderTarget,struct ID2D1BitmapRenderTarget,struct ID2D1DeviceContext6>::PushLayer(struct D2D1_LAYER_PARAMETERS const *,struct ID2D1Layer *)} {...} unsigned int *
+       [41]    0x6dd15c30 {d2d1.dll!D2DDeviceContextBase<...>::PopLayer(void)} {2337640550}    unsigned int *
+       [42]    0x6dd13570 {d2d1.dll!D2DDeviceContextBase<...>::Flush(void)} {2337640550}   unsigned int *
+       [43]    0x6dd189f0 {d2d1.dll!D2DDeviceContextBase<...>::SaveDrawingState(void)} {2337640550}    unsigned int *
+       [44]    0x6dcfc180 {d2d1.dll!D2DDeviceContextBase<...>::RestoreDrawingState(void)} {2337640550} unsigned int *
+       [45]    0x6dcf49d0 {d2d1.dll!D2DDeviceContextBase<...>::PushAxisAlignedClip(void)} {2337640550} unsigned int *
+       [46]    0x6dd13340 {d2d1.dll!D2DDeviceContextBase<...>::PopAxisAlignedClip(void)} {2337640550}  unsigned int *
+       [47]    0x6dcdb410 {d2d1.dll!D2DDeviceContextBase<...>::Clear(void)} {2337640550}   unsigned int *
+       [48]    0x6dcd8720 {d2d1.dll!D2DDeviceContextBase<...>::BeginDraw(void)} {2337640550}   unsigned int *
+       [49]    0x6dcd8900 {d2d1.dll!D2DDeviceContextBase<...>::EndDraw(void)} {2337640550} unsigned int *
+       [50]    0x6dcd2b80 {d2d1.dll!D2DDeviceContextBase<ID2D1DeviceContext6,ID2D1DeviceContext6,null_type>::GetPixelFormat(void)} {...}   unsigned int *
+       [51]    0x6dc81160 {d2d1.dll!D2DDeviceContextBase<struct ID2D1BitmapRenderTarget,struct ID2D1BitmapRenderTarget,struct ID2D1DeviceContext6>::SetDpi(float,float)} {...} unsigned int *
+       [52]    0x6dcfbd00 {d2d1.dll!D2DDeviceContextBase<struct ID2D1BitmapRenderTarget,struct ID2D1BitmapRenderTarget,struct ID2D1DeviceContext6>::GetDpi(float *,float *)const } {...}   unsigned int *
+       [53]    0x6dda1710 {d2d1.dll!D2DDeviceContextBase<struct ID2D1BitmapRenderTarget,struct ID2D1BitmapRenderTarget,struct ID2D1DeviceContext6>::GetSize(void)const } {...} unsigned int *
+       [54]    0x6dcd2230 {d2d1.dll!D2DDeviceContextBase<ID2D1DeviceContext6,ID2D1DeviceContext6,null_type>::GetPixelSize(void)} {...} unsigned int *
+       [55]    0x6dda12d0 {d2d1.dll!D2DDeviceContextBase<struct ID2D1BitmapRenderTarget,struct ID2D1BitmapRenderTarget,struct ID2D1DeviceContext6>::GetMaximumBitmapSize(void)const } {...}    unsigned int *
+       [56]    0x6dda1f40 {d2d1.dll!D2DDeviceContextBase<struct ID2D1BitmapRenderTarget,struct ID2D1BitmapRenderTarget,struct ID2D1DeviceContext6>::IsSupported(struct D2D1_RENDER_TARGET_PROPERTIES const *)const } {...} unsigned int *
+       [57]    0x6dc89b50 {d2d1.dll!D2DDeviceContextBase<ID2D1DeviceContext6,ID2D1DeviceContext6,null_type>::CreateBitmap(void)} {...} unsigned int *
+       [58]    0x6dcfe7f0 {d2d1.dll!D2DDeviceContextBase<ID2D1DeviceContext6,ID2D1DeviceContext6,null_type>::CreateBitmapFromWicBitmap(void)} {...}    unsigned int *
+       [59]    0x6dda59d0 {d2d1.dll!D2DDeviceContextBase<struct ID2D1DeviceContext6,struct ID2D1DeviceContext6,class null_type>::CreateColorContext(enum D2D1_COLOR_SPACE,unsigned char const *,unsigned int,struct ID2D1ColorContext * *)} {...}  unsigned int *
+       [60]    0x6dc835c0 {d2d1.dll!D2DDeviceContextBase<struct ID2D1DeviceContext6,struct ID2D1DeviceContext6,class null_type>::CreateColorContextFromFilename(unsigned short const *,struct ID2D1ColorContext * *)} {...}    unsigned int *
+       [61]    0x6dda5ce0 {d2d1.dll!D2DDeviceContextBase<struct ID2D1DeviceContext6,struct ID2D1DeviceContext6,class null_type>::CreateColorContextFromWicColorContext(struct IWICColorContext *,struct ID2D1ColorContext * *)} {...}  unsigned int *
+       [62]    0x6dcad780 {d2d1.dll!D2DDeviceContextBase<ID2D1DeviceContext6,ID2D1DeviceContext6,null_type>::CreateBitmapFromDxgiSurface(void)} {...}  unsigned int *
+       [63]    0x6dcdce60 {d2d1.dll!D2DDeviceContextBase<ID2D1DeviceContext6,ID2D1DeviceContext6,null_type>::CreateEffect(void)} {...} unsigned int *
+       [64]    0x6dda6230 {d2d1.dll!D2DDeviceContextBase<struct ID2D1DeviceContext6,struct ID2D1DeviceContext6,class null_type>::CreateGradientStopCollection(struct D2D1_GRADIENT_STOP const *,unsigned int,enum D2D1_COLOR_SPACE,enum D2D1_COLOR_SPACE,enum D2D1_BUFFER_PRECISION,enum D2D1_EXTEND_MODE,enum D2D1_COLOR_INTERPOLATION_MODE,struct ID2D1GradientStopCollection1 * *)} {...}   unsigned int *
+       [65]    0x6dc7d8b0 {d2d1.dll!D2DDeviceContextBase<ID2D1DeviceContext6,ID2D1DeviceContext6,null_type>::CreateImageBrush(void)} {...} unsigned int *
+       [66]    0x6dc75640 {d2d1.dll!D2DDeviceContextBase<struct ID2D1DeviceContext6,struct ID2D1DeviceContext6,class null_type>::CreateBitmapBrush(struct ID2D1Bitmap *,struct D2D1_BITMAP_BRUSH_PROPERTIES1 const *,struct D2D1_BRUSH_PROPERTIES const *,struct ID2D1BitmapBrush1 * *)} {...} unsigned int *
+       [67]    0x6dc7d410 {d2d1.dll!D2DDeviceContextBase<struct ID2D1DeviceContext6,struct ID2D1DeviceContext6,class null_type>::CreateCommandList(struct ID2D1CommandList * *)} {...} unsigned int *
+       [68]    0x6dc7a100 {d2d1.dll!D2DDeviceContextBase<struct ID2D1DeviceContext6,struct ID2D1DeviceContext6,class null_type>::IsDxgiFormatSupported(enum DXGI_FORMAT)const } {...}  unsigned int *
+       [69]    0x6dc80620 {d2d1.dll!D2DDeviceContextBase<struct ID2D1DeviceContext6,struct ID2D1DeviceContext6,class null_type>::IsBufferPrecisionSupported(enum D2D1_BUFFER_PRECISION)const } {...}   unsigned int *
+       [70]    0x6dc6d0b0 {d2d1.dll!D2DDeviceContextBase<struct ID2D1DeviceContext6,struct ID2D1DeviceContext6,class null_type>::GetImageLocalBounds(struct ID2D1Image *,struct D2D_RECT_F *)const } {...} unsigned int *
+       [71]    0x6dda8a10 {d2d1.dll!D2DDeviceContextBase<struct ID2D1DeviceContext6,struct ID2D1DeviceContext6,class null_type>::GetImageWorldBounds(struct ID2D1Image *,struct D2D_RECT_F *)const } {...} unsigned int *
+       [72]    0x6dcaad10 {d2d1.dll!D2DDeviceContextBase<struct ID2D1DeviceContext6,struct ID2D1DeviceContext6,class null_type>::GetGlyphRunWorldBounds(struct D2D_POINT_2F,struct DWRITE_GLYPH_RUN const *,enum DWRITE_MEASURING_MODE,struct D2D_RECT_F *)const } {...}   unsigned int *
+       [73]    0x6dc7e2a0 {d2d1.dll!D2DDeviceContextBase<struct ID2D1DeviceContext6,struct ID2D1DeviceContext6,class null_type>::GetDevice(struct ID2D1Device * *)const } {...}    unsigned int *
+       [74]    0x6dcdc240 {d2d1.dll!D2DDeviceContextBase<ID2D1DeviceContext6,ID2D1DeviceContext6,null_type>::SetTarget(void)} {...}    unsigned int *
+       [75]    0x6dc84990 {d2d1.dll!D2DDeviceContextBase<struct ID2D1DeviceContext6,struct ID2D1DeviceContext6,class null_type>::GetTarget(struct ID2D1Image * *)const } {...} unsigned int *
+       [76]    0x6dc804a0 {d2d1.dll!D2DDeviceContextBase<struct ID2D1DeviceContext6,struct ID2D1DeviceContext6,class null_type>::SetRenderingControls(struct D2D1_RENDERING_CONTROLS const *)} {...}   unsigned int *
+       [77]    0x6dc832e0 {d2d1.dll!D2DDeviceContextBase<struct ID2D1DeviceContext6,struct ID2D1DeviceContext6,class null_type>::GetRenderingControls(struct D2D1_RENDERING_CONTROLS *)const } {...}   unsigned int *
+       [78]    0x6dcfc740 {d2d1.dll!D2DDeviceContextBase<ID2D1DeviceContext6,ID2D1DeviceContext6,null_type>::SetPrimitiveBlend(void)} {...}    unsigned int *
+       [79]    0x6dc7cd70 {d2d1.dll!D2DDeviceContextBase<struct ID2D1DeviceContext6,struct ID2D1DeviceContext6,class null_type>::GetPrimitiveBlend(void)const } {...}  unsigned int *
+       [80]    0x6dcfc810 {d2d1.dll!D2DDeviceContextBase<ID2D1DeviceContext6,ID2D1DeviceContext6,null_type>::SetUnitMode(void)} {...}  unsigned int *
+       [81]    0x6dcfbda0 {d2d1.dll!D2DDeviceContextBase<struct ID2D1DeviceContext6,struct ID2D1DeviceContext6,class null_type>::GetUnitMode(void)const } {...}    unsigned int *
+       [82]    0x6dcaaf30 {d2d1.dll!D2DDeviceContextBase<struct ID2D1DeviceContext6,struct ID2D1DeviceContext6,class null_type>::DrawGlyphRun(struct D2D_POINT_2F,struct DWRITE_GLYPH_RUN const *,struct DWRITE_GLYPH_RUN_DESCRIPTION const *,struct ID2D1Brush *,enum DWRITE_MEASURING_MODE)} {...}   unsigned int *
+       [83]    0x6dcda160 {d2d1.dll!D2DDeviceContextBase<ID2D1DeviceContext6,ID2D1DeviceContext6,null_type>::DrawImage(void)} {...}    unsigned int *
+       [84]    0x6dda78d0 {d2d1.dll!D2DDeviceContextBase<struct ID2D1DeviceContext6,struct ID2D1DeviceContext6,class null_type>::DrawGdiMetafile(struct ID2D1GdiMetafile *,struct D2D_POINT_2F const *)} {...} unsigned int *
+       [85]    0x6dda76a0 {d2d1.dll!D2DDeviceContextBase<struct ID2D1DeviceContext6,struct ID2D1DeviceContext6,class null_type>::DrawBitmap(struct ID2D1Bitmap *,struct D2D_RECT_F const *,float,enum D2D1_INTERPOLATION_MODE,struct D2D_RECT_F const *,struct D2D_MATRIX_4X4_F const *)} {...}    unsigned int *
+       [86]    0x6dd0fac0 {d2d1.dll!D2DDeviceContextBase<struct ID2D1DeviceContext6,struct ID2D1DeviceContext6,class null_type>::PushLayer(struct D2D1_LAYER_PARAMETERS1 const *,struct ID2D1Layer *)} {...}   unsigned int *
+       [87]    0x6dc66a30 {d2d1.dll!D2DDeviceContextBase<ID2D1DeviceContext6,ID2D1DeviceContext6,null_type>::InvalidateEffectInputRectangle(void)} {...}   unsigned int *
+       [88]    0x6dc63180 {d2d1.dll!D2DDeviceContextBase<struct ID2D1DeviceContext6,struct ID2D1DeviceContext6,class null_type>::GetEffectInvalidRectangleCount(struct ID2D1Effect *,unsigned int *)} {...}    unsigned int *
+       [89]    0x6dc634d0 {d2d1.dll!D2DDeviceContextBase<struct ID2D1DeviceContext6,struct ID2D1DeviceContext6,class null_type>::GetEffectInvalidRectangles(struct ID2D1Effect *,struct D2D_RECT_F *,unsigned int)} {...}  unsigned int *
+       [90]    0x6dc62b50 {d2d1.dll!D2DDeviceContextBase<struct ID2D1DeviceContext6,struct ID2D1DeviceContext6,class null_type>::GetEffectRequiredInputRectangles(struct ID2D1Effect *,struct D2D_RECT_F const *,struct D2D1_EFFECT_INPUT_DESCRIPTION const *,struct D2D_RECT_F *,unsigned int)} {...} unsigned int *
+       [91]    0x6dda8420 {d2d1.dll!D2DDeviceContextBase<struct ID2D1DeviceContext6,struct ID2D1DeviceContext6,class null_type>::FillOpacityMask(struct ID2D1Bitmap *,struct ID2D1Brush *,struct D2D_RECT_F const *,struct D2D_RECT_F const *)} {...}  unsigned int *
+       [92]    0x6dda5f90 {d2d1.dll!D2DDeviceContextBase<struct ID2D1DeviceContext6,struct ID2D1DeviceContext6,class null_type>::CreateFilledGeometryRealization(struct ID2D1Geometry *,float,struct ID2D1GeometryRealization * *)} {...}  unsigned int *

You can see that the 3 first entries are QueryInterface, AddRef and Release method which is what all interfaces have in their VMT.

fpiette
  • 11,983
  • 1
  • 24
  • 46