class A
{
public:
	 A()
	 {
	 	cout<<"ctor A\n";
	 }

	virtual void func(int x)
	{
	cout<<"\nsj\n";
	}
};
int _tmain(int argc, _TCHAR* argv[])
{
	A objA;
	int *vptr = (int *)*((int *)&objA);// address of the virtual table
	typedef void (*fnptr)(int);
	fnptr f;
	f = (fnptr)*((int *)vptr+0);// address of func() within virtual table
	f(9); // Calling func().  What is going wrong here ???
	return 0;
}

When i call the function pointer, i get a "runtime check failure" (debug error) on VC.
What is it that i am doing wrong ?
The error states ->
" The value of ESP was not properly saved across a function call. This is
actually a result of calling a function with one calling convention with a function
pointer declared with a different calling convention".

Recommended Answers

All 4 Replies

What's wrong with the code include
- way too many casts
- way too many assumptions about the internal (ie undocumented) structure of classes
- using C calling conventions for C++ class member variables.

It's an abomination.

What are you really trying to do?

if your idea was to have a code sample which will help you understand how virtual function calls are implemented by the microsoft compiler:

#include <iostream>

#if defined(_MSC_VER) && (_MSC_VER >= 1200) && defined(_M_IX86) 

struct A
{
  // __stdcall, args passed on stack, 'this' is the first arg
  virtual void __stdcall foo( int x ) = 0 ;

  // __fastcall, args passed using registers if possible
  // 'this' is the first arg, passed in ecx
  // x is the second arg, passed in edx
  virtual void __fastcall bar( int x ) = 0 ;

  // default is __thiscall
  // 'this' is the first arg, passed in register ecx
  // other args passed on stack
  virtual void foobar( int x ) = 0 ;
};

int main()
{
  struct A_vtbl 
  {
    // microsoft compilers order the vtbl as per declaration order
    // required for support for COM vtbls 

    void ( __stdcall* pfn_foo )( A* This, int x ) ;
    void ( __fastcall* pfn_bar )( A* This, int x ) ;
    
    // __thiscall: pass first arg in ecx, rest on stack
    void ( __thiscall* pfn_foobar )( A* This, int x ) ;

    // other stuff; 
    // rtti etc.
  };

  struct A_shadow
  {
    A_vtbl* vtbl_pointer ;
  };

  struct derived_class : A
  {
    virtual void __stdcall foo( int x )
    { std::cout << "derived_class::foo( " << x << " )\n" ; }

    virtual void __fastcall bar( int x )
    { std::cout << "derived_class::bar( " << x << " )\n" ; }

    virtual void foobar( int x ) 
    { std::cout << "derived_class::foobar( " << x << " )\n" ; }
  };

  derived_class derived ;
  union
  {
    A* pa ;
    A_shadow* pa_alias ;
  };
  pa = &derived ;

  pa_alias->vtbl_pointer->pfn_foo( pa, 99999 ) ;
  pa_alias->vtbl_pointer->pfn_bar( pa, 12345 ) ;
  pa_alias->vtbl_pointer->pfn_foobar( pa, -54321 ) ;
}
#else
  #error unsupported compiler
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) && defined(_M_IX86)

Hmm, can that union trick work with reinterpret_cast also?

i.e.--

#include <iostream>

using namespace std;

int main(){
    union{
        short *a;
        float *b;
    };

    float value = .1f;
    b = &value;

    std::cout << *a << std::endl;

    short *s;
    float *f;

    f = &value;
    s = reinterpret_cast<short*>(f);

    std::cout << *s << std::endl;
    return 0;
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.