Jump to content
  • Advertisement
Sign in to follow this  
jamesleighe

Run-Time Check Failure #0 Fun Stadium

This topic is 2478 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

(C++, MSVC, DLLS and LIBS are being used)
Well, right to the issue!


This is called when you are finished with the class.

FORCEINLINE void
TriangleSoup::Release( )
{
// NOW: bad calling convention or stack mutililation
PhysicsAPIInternal()->RemoveFromSimulation( this );

delete this;
}

The commented line causes the following error:
"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."

I don't really know why!

This code is run inside the game dll, TriangleSoup is in a lib and PhysicsAPIInternal is calling a global gotten from the physicssystem dll.


Here is some of the relavent sources truncated to important bits:

TriangleSoup.h

class TriangleSoup: public ICollide
{
void Link( OcTree< ICollide* >::Node* node );
const Vector< OcTree< ICollide* >::Node* >* GetLinks( );
void Unlink( );

void Release( );

private:
Vector< OcTree< ICollide* >::Node* > backlinks_; // broadphase backlinks
};

#include "trianglesoup.inl"


TriangleSoup.inl

FORCEINLINE void
TriangleSoup::Link( OcTree< ICollide* >::Node* node )
{
backlinks_.InsertBack( node );
}

FORCEINLINE const Vector< OcTree< ICollide* >::Node* >*
TriangleSoup::GetLinks( )
{
return &backlinks_;
}

FORCEINLINE void
TriangleSoup::Unlink( )
{
for( uint32 i = 0; i < backlinks_.GetCount(); ++i )
{
backlinks_[ i ]->RemoveObject( this );
}

backlinks_.RemoveAll();
}

FORCEINLINE void
TriangleSoup::Release( )
{
// NOW: bad calling convention or stack mutililation
PhysicsAPIInternal()->RemoveFromSimulation( this );

delete this;
}


PhysicsSystem.h

class IPhysicsSystemInternal
{
public:
virtual ~IPhysicsSystemInternal( ) { ; }

virtual void AddToSimulation( ICollide* collide ) = 0;
virtual void RemoveFromSimulation( ICollide* collide ) = 0;
};

class PhysicsSystem: public IPhysicsSystemInternal, public IPhysicsSystem
{
public:
PhysicsSystem( );
~PhysicsSystem( );

void AddToSimulation( ICollide* collide );
void RemoveFromSimulation( ICollide* collide );
};

// Internal Accessor
FORCEINLINE IPhysicsSystemInternal* PhysicsAPIInternal( )
{
extern IPhysicsSystem* _g_PhysicsSystemInstance;
Assert( _g_PhysicsSystemInstance );
return (IPhysicsSystemInternal*)_g_PhysicsSystemInstance;
}


PhysicsSystem.cpp


void
PhysicsSystem::AddToSimulation( ICollide* collide )
{
// link to octree
Extents extents;
collide->GetExtents( extents );
ocTree_.AddObject( collide, extents );

// add to simualted entities
simulatedCollides_.InsertBack( collide );
}

void
PhysicsSystem::RemoveFromSimulation( ICollide* collide )
{
// unlink from octree
collide->Unlink();

// remove from simulated entities
simulatedCollides_.FindFirstAndRemove( collide );
}


I'm not sure where to start here!
Thanks allot guys as usual.

Share this post


Link to post
Share on other sites
Advertisement
Also, it only happenes when I use PhysicsAPIInternal() (which casts the global to a IPhysicsSystemInternal) because I declared the same methods in IPhysicsSystem (the public interface) and it works fine!

But now I have internals exposed.

Share this post


Link to post
Share on other sites
...
Ok, a few things...
Does IPhysicsSystemInternal derive from IPhysicsSystem? No? Then why do you force it down that route with this cast:


extern IPhysicsSystem* _g_PhysicsSystemInstance;
Assert( _g_PhysicsSystemInstance );
return (IPhysicsSystemInternal*)_g_PhysicsSystemInstance;
.

C casts are BAD. Period. Use C++ casts. Chances are high that because you're forcing the pointer from type A to type B, where A not related to B, you've just screwed which virtual table you're actually pointing to.

Share this post


Link to post
Share on other sites
Errors like this are making a pretty convincing argument to go back to c++ style casting.

Anyway, 'IPhysicsSystemInternal' does not inherit 'IPhysicsSystem' (ATM, but it is supposed to at some point) so you're right there.

'_g_PhysicsSystemInstance' is supposed to point to an instance of 'PhysicsSystem' casted to an 'IPhysicsSystem' for public access. Since 'PhysicsSystem' inherits them both, can't I cast the '_g_PhysicsSystemInstance' either way indiscriminately?

It seems not, but I'm pretty unsure why this is.

Thanks!

Share this post


Link to post
Share on other sites
In this case you can use a dynamic_cast to get from one interface to the other. A C style cast will just reinterpret the address as the other interface, but with multiple interfaces the interfaces have different addresses for the same object.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!