Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call
13,863
Solution 1
Because you're using multiple inheritance, the vftable
pointer to what is expected to be a MyInterface*
is actually a pointer to a QGraphicsLineItem vftable
.
A dynamic_cast
would solve the issue because it will return the correct vftable
MyInterface* mInterface = dynamic_cast<MyInterface*>(item);
A simple example:
class A
{
public:
virtual void foo() = 0;
};
class B
{
public:
virtual void goo() {};
};
class C : public B, public A
{
public:
virtual void foo() {};
};
//....
B* c = new C; // c is at 0x00a97c78
A* a = (A*)c; // a is at 0x00a97c78 (vftable pointer of B)
A* a1 = dynamic_cast<A*>(c); // a1 is at 0x00a97c7c (vftable pointer of A)
Solution 2
You issue will be fixed if you use a dynamic cast
MyInterface* mInterface = dynamic_cast<MyInterface*>(item);
This questions deals various C++ casts and when to use them. In your case because of multiple inheritance you should be using dynamic casts
Author by
Ben Burnett
Updated on June 18, 2022Comments
-
Ben Burnett almost 2 years
I created a simple program that demonstrates the runtime error I'm getting with my Qt application that uses multiple inheritance. The inheritance tree looks like:
QGraphicsItem (abstract) \ QGraphicsLineItem MyInterface (abstract) \ / \ / MySubclass
And here is the code:
/* main.cpp */ #include <QApplication> #include <QGraphicsScene> #include <QGraphicsLineItem> //simple interface with one pure virtual method class MyInterface { public: virtual void myVirtualMethod() = 0; }; //Multiple inheritance subclass, simply overrides the interface method class MySubclass: public QGraphicsLineItem, public MyInterface { public: virtual void myVirtualMethod() { } }; int main(int argc, char** argv) { QApplication app(argc, argv); //init QApplication QGraphicsScene *scene = new QGraphicsScene(); //create scene scene->addItem(new MySubclass()); // add my subclass to the scene Q_FOREACH(QGraphicsItem *item, scene->items()) // should only have one item { MyInterface *mInterface = (MyInterface*)item; // cast as MyInterface mInterface->myVirtualMethod(); // <-- this causes the error } return 0; }
Debugging in visual studio results in a runtime error when my interface method is called:
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.
Any idea what the problem is?
-
ceztko about 6 yearsAlso applies when wrapping c++ pointers of objects in C# with P/Invoke and try to marshal interface pointers. A dynamic cast from a common ancestor type to the target interface is needed.