能帮我解释一下C++类成员函数地址与C++类对象地址的关系吗?在做Thunk时,遇了问题

BlueAtlantis 2003-07-18 01:53:12
看这个月的杂志有一个关于Thunk的文章,非常不错。
于是我自己也想写一个。
突然发现他的代码里有这么一句来取得成员函数地址.
m_relproc = (int) proc - ((int) this + 1);

于是,我就胡涂了。以前我认为成员函数地址是静态,根据传进来的this指针来分别不同的对象。
可是这个是成员函数地址的运算须与this相减。

所以,我需要了解释C++类成员函数地址与C++类对象地址的关系.
谢谢。
...全文
291 7 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
BlueAtlantis 2003-07-22
  • 打赏
  • 举报
回复
呵呵,太感谢了,太感谢了.
Analyst 2003-07-18
  • 打赏
  • 举报
回复
jmp指令后面带的从来都是是地址偏移量,只有call指令后面带的才是绝对地址。
WIN32使用32位flat mode寻址,指令段、数据段、堆栈段都在相同的地址空间里,this是thunk对象的起始地址,就是mov dword ptr [esp+0x4], pThis 这个指令的起始地址,this + 1是jmp指令后的地址,也就是当前的指令地址,
(int) proc - ((int) this + 1);这里写错了,应该是(int) proc - (int)(this + 1);才对
通过(int) proc - (int)(this + 1);就计算出了当前指令地址到proc函数地址的偏移量。
arxing 2003-07-18
  • 打赏
  • 举报
回复
我搞错了,经过我观察,也许正确的说法如下:
在汇编语法中,jmp后面的那个值是跳转的地址,可是在转换成二进制后就是相对当前地址的偏移量。
arxing 2003-07-18
  • 打赏
  • 举报
回复
另外,为了怕我误导你,先声明一下我自己对汇编也只是三脚猫的功夫,至于这里为什么是相对寻址,有些时候jmp又是绝对寻址的,你还是去找一些权威的汇编文档看看。
arxing 2003-07-18
  • 打赏
  • 举报
回复
这个this指针是thunk的指针,也就是thunk函数的地址,而不是传进来的(一般是窗口类对象)指针。jmp采用的是相对寻址。
struct _stdcallthunk
{
DWORD m_mov; // mov dword ptr [esp+0x4], pThis (esp+0x4 is hWnd)
DWORD m_this; //
BYTE m_jmp; // jmp WndProc
DWORD m_relproc; // relative jmp
}
从这个结构可以看到,this+1就是 jmp ... 下一个指令的地址,加上m_relproc的值正好是目标proc的值。
BlueAtlantis 2003-07-18
  • 打赏
  • 举报
回复
OK.

template<class T>
class CStdCallThunk
{
BYTE m_mov;
DWORD m_this;
BYTE m_jmp;
int m_relproc;

public:
typedef void (T::*TMFP)();
void InitThunk(TMFP method, const T* pThis)
{
m_mov = 0xB9;
m_this = (DWORD)pThis; WNDPROC
m_jmp = 0xE9;
m_relproc = int(method) - int(this + 1); //主要是这个减运算不明白

FlushInstruction(GetCurrentProcess(), this, sizeof(*this));
}

FARPROC GetThunk() const
{
return (FARPROC)this;
}
};
lglchf 2003-07-18
  • 打赏
  • 举报
回复
代码给的全面一些好吗?

3,248

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧