【问题标题】:How to find address of pointer to interface in C++?如何在 C++ 中找到指向接口的指针的地址?
【发布时间】:2017-04-20 12:37:40
【问题描述】:

获取接口并调用方法:

IFileOpenDialog *pFileOpen;
CoCreateInstance(__uuidof(FileOpenDialog), NULL, CLSCTX_INPROC_SERVER,IID_PPV_ARGS(&pFileOpen));
pFileOpen->Show(NULL);

在汇编中是:

mov         eax,pFileOpen
mov         ecx,dword ptr [eax]  
mov         edx,pFileOpen
push        edx  
mov         eax,dword ptr [ecx+ offset_Show]
call        eax  

也就是说ecx是指向VMT的指针,[ecx + offset_Show]是方法Show。 如何获得offset_Show,希望尽可能高。 pFileOpen->显示为指针不可编译。

【问题讨论】:

  • 使用微软的 offsetof() 宏。 msdn.microsoft.com/en-us/library/dz4y9b9a.aspx
  • 你必须在#include shobjidl.h 之前#define CINTERFACE,然后你可以访问vtbl 声明并且offsetof(IFileDialogVtbl, Show) 将起作用。但这对程序的其余部分具有很大的破坏性。 Google "c++ get offset of virtual function in vtbl" for the hacks。

标签: c++ com


【解决方案1】:

找到解决方案。为了可编译性,需要单独的 C 源代码来获得 VMT 中的偏移量。

C++ 源代码:

#include <shobjidl.h> 
#include <atlbase.h>
extern "C" int getOffsetIFileDialogVtblShow();
IFileOpenDialog *pFileOpen = ...; //get from somewhere
//pointer to VMT
unsigned char *pcFileOpen = (unsigned char *)(*(DWORD*)(unsigned char *)pFileOpen);
pcFileOpen = (unsigned char *)(*(DWORD*)pcFileOpen);
int offs = getOffsetIFileDialogVtblShow();
//pointer to Show() at pcFileOpen + offs, put hook here
fprintf(fLog,"\nFileOpenDialog::IFileOpenDialog->Show at %.8X value %.8X",pcFileOpen + offs,*(DWORD*)(pcFileOpen + offs));      

C 源代码

#include <stddef.h> //for offsetof
#define CINTERFACE
#include <shobjidl.h> 

int getOffsetIFileDialogVtblShow()
{
    return = offsetof(IFileDialogVtbl, Show);
}

【讨论】:

    【解决方案2】:

    要获得正常功能的地址,您可以使用function pointers。另请参阅 this Stackoverflow post 获取指向类方法的函数指针。

    指向接口 istelf 的指针的地址正是您在代码中所做的:&amp;pFileOpen

    【讨论】:

    • 这不适用于接口,至少对于 MSVC10。无效 *pShow = &pFileOpen->显示;导致“错误 C2276:'&':对绑定成员函数表达式的非法操作”。智能:“绑定函数只能用于调用”。地址实际上是在调用之前如上所述计算的,并且事先不知道,但是偏移量是硬编码的!请提出可行的确切语法。
    • int offs = offsetof(IFileOpenDialog,Show); - 同样的错误。类似的文章,他们写道这是不可能的:stackoverflow.com/questions/2125862/….
    • 如果我正确理解您的问题,this question 的答案可能会引导您找到解决方案。
    • 另外,请记住,如果可以使用&amp;IFileOpenDialog::Show而不是&amp;pFileOpen-&gt;Show检索指向成员函数的函数指针。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-30
    相关资源
    最近更新 更多