马上加入TC
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
本帖最后由 sam7894604 于 2016-3-26 17:22 编辑
- 调用约定是啥意思?
以 C++ 语言来说,根据查询所得资料(参数传递和命名约定)
使用的调用约定有 __cdecl、__clrcall、__stdcall、__fastcall、__thiscall、__vectorcall 等类型…详细差别可自行百度
由于 TC 属于解释型语言,调用约定并不是我门 TC 程序员所能碰上的,但还好 TC 提供了 dllcall、pointercall 两个动态库 API
而这两个动态库 API 所用上的原理类似 __stdcall (实际调用) 与 __cdecl (代码写法),用于调用 __stdcall 约定的 Win32 API
本帖主题 __thiscall 正好有 __stdcall(this 指针存放在 ecx 寄存器) 与 __cdecl (this 指针存放堆栈最后)之特性
那么也就是说利用 pointercall 即可实现 __thiscall 调用约定!
- this 是啥意思?
以 C++ 语言来说,根据查询所得资料(C++ this指针详解)
this 是C++中的一个关键字,也是一个常量指针,指向当前对象(具体说是当前对象的首地址)。通过 this,可以访问当前对象的成员变量和成员函数。
所以 TC 中的 com() API 其实就是获取对象的 this 指针,而此指针及可访问成员变量或调用成员函数
以大漠来说,Ver() 只是成员函数之一,依样可以通过 this 指针调用!部份语言的免注册大漠也是类似原理…
- dm = com("dm.soft")
- dm.Ver()
复制代码
- TC 实现过程
每一个成员函数,都有一个对应指针的偏移值,为了方便编写代码以及实现通用写法…必须传入 index 来指明要调用的函数及 this 指针来计算函数指针
依据上述过程写了一个汇编中转,不需要太多处理,剩余收尾都将交由被调用方自行解决!
汇编中转代码如下:
mov ecx,dword ptr [esp+04h] | //取出 index 值,是 pointercall 的第一个必填参数 | mov eax,dword ptr [esp+08h] | //取出 this 指针,是 pointercall 的第二个必填参数 | mov eax,dword ptr [eax] | //从 this 指针获取虚函数表指针 | mov ecx,dword ptr [eax+ecx*4] | //根据 index * 4 算出偏移,并取出函数入口 | mov dword ptr [esp+04h],ecx | //将函数入口覆盖到 index 参数 | pop eax | //弹出返回指针 | xchg dword ptr [esp],eax | //此时 [esp] 指向函数入口,并且跟 eax 做交换,以此恢复 stdcall 调用结构 | jmp eax | //跳至函数入口... 后面交由com方法或属性自行处理 thiscall 的形式 |
代码直上:
具体使用方式将在下次开源中解说
如果本帖对您有所帮助,请给与评分鼓励! |