Chinaunix首页 | 论坛 | 博客
  • 博客访问: 831244
  • 博文数量: 158
  • 博客积分: 4380
  • 博客等级: 上校
  • 技术积分: 2367
  • 用 户 组: 普通用户
  • 注册时间: 2006-09-21 10:45
文章分类

全部博文(158)

文章存档

2012年(158)

我的朋友

分类: C/C++

2012-11-14 16:42:45

// 理论上而言调用一个类的成员函数只需要知道类实例的地址和类成员函数的地址和类成员函数参数类型等,而不需要知道类的类型,但除了使用汇编之外却别无它法
#include
#include
using namespace std;

// 参数分别是 类实例地址, 类成员函数地址, 类成员函数参数
// 之所以使用...作参数,因为了去掉一些类型转换
__declspec(naked) bool print( ... )
{
    __asm {
        // 压入了3个字节长度的变量,以后的esp要加上12
        push ebx
        push esi
        push edi
        mov eax, dword ptr [(esp+12)+4] // 将对象地址保存到EAX
        mov ebx, dword ptr [(esp+12)+8] // 将类成员地址保存到EBX
        mov ecx, dword ptr [(esp+12)+0] // 此函数的返回地址
        mov cl, byte ptr [ecx+2]   // __cdecl返回地址处是个add ebp,?语句,取得?,即参数长度
        movzx ecx, cl              // 将cl扩展到ecx中
        sub ecx, 8                 // 对象地址4字节长+成员函数地址4字节长
        sub esp, ecx
        // memcpy( esp, esp+ecx+12, ecx )
        shr ecx, 2                 // ecx /= 4
        lea esi, dword ptr [(esp+12)+ecx*4+12]
        lea edi, dword ptr [esp]
        rep movsd
        mov ecx, eax         // 将类对象地址传入ecx,这是thiscall调用约定
        call ebx             // call 成员函数
        pop edi
        pop esi
        pop ebx
        ret
    }
}

// 以下为测试代码
struct cls1
{
    int i;
    cls1():i(1234){}
    virtual bool memfun( const char* str )
    {
        cout << i << ' ' << str << endl;
        return true;
    }
};
struct cls2 : cls1
{
    int j;
    cls2():j(4321){}
    virtual bool memfun( const char* str )
    {
        cout << i << ' ' << j << ' ' << str << endl;
        return false;
    }
};

int main()
{
    cls1 a;
    cls2 b;
    bool f1 = print( &a, cls1::memfun, "base" );
    cout << f1 << endl;
    bool f2 = print( &b, cls1::memfun, "derive" ); // 这里没有使用cls2::memfun,可以体现多态
    cout << f2 << endl;

    system( "Pause" );
    return 0;
}
阅读(1577) | 评论(7) | 转发(0) |
给主人留下些什么吧!~~

网友评论2012-11-14 16:44:32

周星星
谢谢,我做这个尝试是为了与其他程序的接**互,而模板只能在编译器确定,再次感谢!

网友评论2012-11-14 16:44:12

辣子鸡丁
可以用模板来尝试一下。

struct cls1
{
int i;
cls1():i(1234){}
virtual bool memfun( const char* str )
{
cout << i << ' ' << str << endl;
return true;
}
};
struct cls2 : cls1
{
int j;
cls2():j(4321){}
virtual bool memfun( const char* str )
{
cout << i << ' ' << j << ' ' << str << endl;
re