有请高手帮忙--2004-08-17 22:46:48
我有一个疑难问题解决不了。

需要懂得argument passing stack frame才能解决的问题,下面是例子:用GNU compiler,一切都很好,但用VC++,就crash了。

如果你能帮我提示,将不胜感激。请email: *****ss1966@yahoo.com

PS.: 有人告诉我只能用Assembly写,但我一点都不懂Assembly。我看了一个解释,什么也看不明白。。。http://www.codeguru.com/Cpp/misc/misc/stack/article.php/c3875

-----------------header file classdef.hpp-------------
#include “iostream"
#include ”stdarg.h"

/*
**
** CBase
** ^ ^
** / \
** / \
** / \
** / \
** CWrapper -----> CDerive
**
**
** CWrapper class knows everything about CBase. Its purpose is
** for message passing to the real object (_base)
**
*/

#define PASTE(x, y) x ## y

#define VFN_DECL(n) \
virtual void *PASTE(VFn,n)(...)

class CBase
{
public:

virtual void foo0() {}

CBase();
virtual ~CBase();

virtual void foo1();
virtual void foo2();
virtual int foo3(int, double);
virtual void foo4(const char *, double);

private:

// to be used specifically by CWrapper
friend class CWrapper;
void* callVirt(int n, va_list ap);

};

class CWrapper : public CBase
{
public:

virtual void foo0() {} // vf 1

CWrapper(CBase *base) :
_base(base) {
}

virtual ~CWrapper(); // vf 2

virtual void foo1(); // vf 3
virtual void foo2(); // vf 3
virtual int foo3(int, double); // vf 3
virtual void foo4(const char *, double); // vf 3

// define a big virtual table
VFN_DECL(7);
VFN_DECL(8);
VFN_DECL(9);
VFN_DECL(10);
VFN_DECL(11);
VFN_DECL(12);
VFN_DECL(13);
VFN_DECL(14);
VFN_DECL(15);

private:

// the real object
CBase *_base;

};

class CDerive : public CBase
{
public:

virtual void foo0() {}

CDerive() {}
virtual ~CDerive();

virtual void foo2();
virtual void foo4(const char *, double);

// additional virtual functions
virtual void foo5();
virtual int foo6(const char *, double);
virtual void foo7();
virtual char * foo8(double, int, float, char, char *, double);
virtual void foo9();

};

-------------------source file classdef.cpp---------------------
#include "classdef.hpp"

typedef void* (*vfunc)(CBase*, ...);

// call nth virtual function
void* CBase::callVirt(int n, va_list ap)
{
vfunc **vf = (vfunc**)this;
int pos=n;

/*
** Note: GNU's destructor occupy 2 entries
*/

#ifdef WNT
pos--;
#endif

// assuming max args are 9!
const int MAX_ARGS = 9;
unsigned long arg[MAX_ARGS];

for (int i=0; i < MAX_ARGS; i++) arg[i] = va_arg(ap, unsigned long);

void* result = (*vf)[pos](this,
arg[0], arg[1], arg[2],
arg[3], arg[4], arg[5],
arg[6], arg[7], arg[8]);

return result;
}

CBase::CBase()
{
std::cout << "CBase::CBase called\n";
}

CBase::~CBase()
{
std::cout << "\nCBase::~CBase called\n";

}

void CBase::foo1()
{
std::cout << "CBase::foo1 called\n";
}

void CBase::foo2()
{
std::cout << "CBase::foo2 called\n";
}

int CBase::foo3(int i, double d)
{
std::cout << "CBase::foo3 called"
<< ", i = " << i
<< ", d = " << d
<< std::endl;

return int(i+d);

}

void CBase::foo4(const char *s, double d)
{
std::cout << "CBase::foo4 called"
<< ", s = " << s
<< ", d = " << d
<< std::endl;
}

/////////////////////////////////////////////////

CWrapper::~CWrapper()
{
std::cout << "\nCWrapper::~CWrapper called\n";
}

void CWrapper::foo1()
{
_base->foo1();

}

void CWrapper::foo2()
{
_base->foo2();

}

int CWrapper::foo3(int i, double d)
{
return _base->foo3(i, d);

}

void CWrapper::foo4(const char *s, double d)
{
_base->foo4(s, d);

}

#ifdef WNT
#define VFN_IMPL(n) \
void *CWrapper::PASTE(VFn,n)(...) \
{ \
va_list ap; \
va_start(ap, *this); \
void *r = _base->callVirt(n, ap); \
va_end(ap); \
return r; \
}
#else
#define VFN_IMPL(n) \
void *CWrapper::PASTE(VFn,n)(...) \
{ \
va_list ap; \
va_start(ap, this); \
void *r = _base->callVirt(n, ap); \
va_end(ap); \
return r; \
}
#endif
VFN_IMPL(7)
VFN_IMPL(8)
VFN_IMPL(9)
VFN_IMPL(10)
VFN_IMPL(11)
VFN_IMPL(12)
VFN_IMPL(13)
VFN_IMPL(14)
VFN_IMPL(15)

//////////////////////////////////

CDerive::~CDerive()
{
std::cout << "CDerive::~CDerive called\n";

}

void CDerive::foo2()
{
std::cout << "CDerive::foo2 called\n";

}

void CDerive::foo4(const char *s, double d)
{
std::cout << "CDerive::foo4 called"
<< ", s = " << s
<< ", d = " << d
<< std::endl;

}

void CDerive::foo5()
{
std::cout << "CDerive::foo5 called\n";

}

int CDerive::foo6(const char *s, double d)
{
std::cout << "CDerive::foo6 called"
<< ", s = " << s
<< ", d = " << d
<< std::endl;

return 99;
}

void CDerive::foo7()
{
std::cout << "CDerive::foo7 called\n";

}

char * CDerive::foo8(double a, int b, float c, char d, char *e, double f)
{
std::cout << "CDerive::foo8 called: "
<< "a = " << a
<< ", b = " << b
<< ", c = " << c
<< ", d = " << d
<< ", e = " << e
<< ", f = " << f
<< std::endl;

return e;

}

void CDerive::foo9()
{
std::cout << "CDerive::foo9 called\n";

}

----------main.cpp------------
#include "classdef.hpp"

int main()
{
CDerive *obj = (CDerive*) new CWrapper(new CDerive());

printf("-------------------------------\n");
obj->foo1();
obj->foo2();
obj->foo3(3, 4.43);
obj->foo4("aaa", 3.4);
obj->foo5();
obj->foo6("ccc", 3.2);
printf("foo6 = %d\n", obj->foo6("This is a test", 5.2321));
obj->foo7();
printf("foo8 = %s\n", obj->foo8(2.345, 5, 3.21f, 'c', "String Array", 63.455));
obj->foo9();

printf("-------------------------------\n");

return 0;
}
tty2004-08-18 01:50:18
查查 __cdecl 啥意思
BBBKKKSSS2004-08-18 04:29:04
看你的邮件, 有问题再给我发信