我有一个指向 IDirect3DDevice9 接口的指针,它有 119 个方法(包括 3 个标准方法)在 d3d9.dll 中实现。
我需要在我的 Delphi 代码中获取接口方法 EndScene() 和 Present() 相对于库开头(指向 DLL 的指针)的偏移量(以字节为单位)。
var:
g_pD3DDevice: IDirect3DDevice9;
ProcAddr: Pointer;
hD3D9: HMODULE;
Present9 : DWORD;
EndScene9: DWORD;
implemenation:
hD3D9 := LoadLibrary('d3d9');
ProcAddr := GetProcAddress(hD3D9, 'Direct3DCreate9');
...
pD3D.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, TargetHandle, D3DCREATE_SOFTWARE_VERTEXPROCESSING, @D3DPP, g_pD3DDevice);
我假设在 VMT 中 Present() 方法排在第 17 位(从 0 开始),而 EndScene() 排在第 42 位,因为它写在 d3d9.dll 头文件中。
但我认为像这样计算偏移量不是一个好主意:
Present9 := DWORD(g_pD3DDevice) + (17 * 4) - DWORD(hD3D9);
EndScene9 := DWORD(g_pD3DDevice) + (42 * 4) - DWORD(hD3D9);
请告诉我这个问题的最佳解决方案!
这个解决方案是在网上找到的。
一个示例实现是:
1)我声明所需方法的过程类型
2)我声明了一个这种类型的变量
3)我实现了通过编号获取接口方法的过程
4)现在我们通过序号获取接口方法并调用它
接口类型变量是指向
Interface Method Table (IMT)-接口方法表的指针,其中包含指向相应方法代码的指针:Delphi 有一个特殊的汇编程序指令 -
VMTOFFSET,它允许您获取虚拟方法地址相对于虚拟方法表 (VMT) 开头的偏移量(以字节为单位)http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Assembler_Syntax
因此,知道我们需要的方法的名称,我们可以获得指向其代码的指针:
也没有必要计算方法的序数。