Jump to content
  • Advertisement
Sign in to follow this  
Hardguy

virtual Release / AddRef methods cause crash

This topic is 2676 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

I am having problems when using virtual functions for the release and addref functions. I have base class that the reference classes inherit from:

class iScriptReferenceClass
{
public:
iScriptReferenceClass() : mlScriptable_RefCount(1) {}

virtual void Scriptable_AddRef() const=0;
virtual void Scriptable_Release()const=0;

protected:
mutable int mlScriptable_RefCount;
};


I then create a class that implements the Scriptable_AddRef and Scriptable_Release.


void Scriptable_AddRef() const { mlScriptable_RefCount++; } \
void Scriptable_Release() const { if(--mlScriptable_RefCount==0) hplDelete( (aClass*) this); } \


I add the functions like this:


mpEngine->RegisterObjectBehaviour(msCurrentName.c_str(), asBEHAVE_ADDREF,"void f() const", asMETHOD(cImplementedClass, Scriptable_AddRef), asCALL_THISCALL);
mpEngine->RegisterObjectBehaviour(msCurrentName.c_str(), asBEHAVE_RELEASE,"void f() const", asMETHOD(cImplementedClass, Scriptable_Release), asCALL_THISCALL);


However, doing this makes the app crash when the script deletes the reference.

However, if I change the interface and remove the (pure) virtual methods like this:
class iScriptReferenceClass
{
public:
iScriptReferenceClass() : mlScriptable_RefCount(1) {}

virtual void Scriptable_AddRef() const=0;
virtual void Scriptable_Release()const=0;

protected:
mutable int mlScriptable_RefCount;
};


There is not crash and everything works!

Is there something with the virtual method part that I am doing horribly wrong? Or should that part work? If all looks okay then I will make some more detailed tests and see.

Share this post


Link to post
Share on other sites
Advertisement
By any chance, does your cImplementedClass derive from another class than IScriptReferenceClass which have some virtual functions too?
If so it's your cast in your hplDelete in the release that may cause you some troubles. You want to use a static_cast instead of (bad) C-style class.

Share this post


Link to post
Share on other sites
Is your destruction declared as virtual?If you set a break point in Scriptable_Release, is the this pointer actually pointing to the right class? You don't use virtual inheritance, do you? Method pointers for classes that use virtual inheritance aren't supported as they do not contain all the information required to resolve the actual function to call.

Share this post


Link to post
Share on other sites
EDIT: Was too fast and thought Quitouff's suggestion solved it, it did NOT.

WitchLord:
No virtual inheritance used. I just have pure virtual functions that I then implement. There is multiple inheritance involved though (as Quitouff suspected) and cImplementedClass inherits from two clases. Going to add break point and see if I can get more info.

Quitouff:
This is kinda strange. I use a macro:

#define kScriptHandleRefManagerInit(aClass) \
public: \
void Scriptable_AddRef() { mlScriptable_RefCount++; } \
void Scriptable_Release() { if(--mlScriptable_RefCount==0) hplDelete( static_cast<aClass*>(this) ); } \


and then add this like
class cImplementedClass {
kScriptHandleRefManagerInit(cImplementedClass)
...
}


Why do I need to cast at all? If I do not cast, the compiler seem to interpret this as void*, which seem strange to me.

Share this post


Link to post
Share on other sites
After making a rebuild it turns out I could skip the casting altogether, who wierd as it complained earlier.

Actually, hplDelete should not be a problem, because it seems like the error occurs before it is called. Actually neither Scriptable_AddRef or Scriptable_Release gets called.

If I add (empty) functions instead of member methods it also works fine, so the problem must lie in when adding the member methods somehow.

The crash is at:

> Test_ScriptRenderDebug.exe!asCContext::ExecuteNext() Line 1288 C++
> Test_ScriptRenderDebug.exe!asCContext::Execute() Line 983 + 0x7 bytes C++
> Test_ScriptRenderDebug.exe!hpl::cScriptContextAS::RunPrepared() Line 127 + 0x15 bytes C++
[/quote]

Share this post


Link to post
Share on other sites
For the cast, well I assumed you needed it because of some encapsulation issue, but if your hplDelete works like a standard delete and you didn't put the cast to workaround some private destructor, you should not need to cast, but if you do cast anyway you may be in trouble with a C-style cast because when you use multiple inheritance involving virtual methods in several branches, there are some pointer arithmetic needed to be done on casts (which C-Style class do not do).

Share this post


Link to post
Share on other sites
Just for completion's sake I tried with delete instead of hplDelete(...) and the problem remains.

Also tried to remove the mutliple inherance (so the top class only inherited from iScriptReferenceClass) and that made the crash go away.

So I am pretty sure now that the problem is that method pointers I send to AngelScript are not good for some reason.

Share this post


Link to post
Share on other sites
Yep, I saw your last message after I posted mine on the casts. The purpose was not for you to test some more things, it was just to explain why I thought there may have been some cast issue. But obviously as stated in the post I did not see, it's not what's causing your crash, but I do not know AngelScript enough to understand what else could go wrong in your case sorry.

Share this post


Link to post
Share on other sites
I will try and make a test program tomorrow and see if I can reproduce. Unless this is some know error I am guessing my current info is not good enough to see if it is something I caused or if it lies in the engine.

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!