🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

C++ class destroyed twice?

Started by
1 comment, last by Zylann 9 years, 6 months ago

Hello,

I'm trying to bind a non-template value type based on iraxef's reflection proposal, but I'm facing a weird runtime crash...
It appears that when ~CScriptType is called for the first time, it has already been destroyed Oo
(when I debug ~CScriptType, members are fucked up, addresses are 0xcdcdcdcd or unreadable, and the first call to m_ot->Release() creates the crash)

What I have in AS:


    SomeClass c;
    Type t(c); // Just instantiate a Type

Here is how I register the class:


    r = e.RegisterObjectType("Type", sizeof(CScriptType), asOBJ_VALUE | asOBJ_APP_CLASS_DA); assert(r >= 0);

    r = e.RegisterObjectBehaviour("Type", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(CScriptType_DefaultConstruct), asCALL_CDECL_OBJLAST); assert(r >= 0);

    r = e.RegisterObjectBehaviour("Type", asBEHAVE_CONSTRUCT, "void f(const ?&in)", asFUNCTION(CScriptType_InstanceConstruct), asCALL_GENERIC); assert(r >= 0);
    r = e.RegisterObjectBehaviour("Type", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(CScriptType_Destruct), asCALL_CDECL_OBJLAST); assert(r >= 0);

static void CScriptType_DefaultConstruct(void * mem)                               { new(mem)CScriptType(NULL); }
static void CScriptType_Destruct(CScriptType *obj)                                 { obj->~CScriptType(); }

// Note: generic calling convention was used to have access to the engine,
// so we can get the asIObjectType from the type ID
static void CScriptType_InstanceConstruct(asIScriptGeneric * g)
{
    int typeID = g->GetArgTypeId(0);
    void * mem = g->GetArgAddress(0);

    asIObjectType * ot = g->GetEngine()->GetObjectTypeById(typeID);

    if (strcmp(ot->GetNamespace(), "") == 0 && strcmp(ot->GetName(), "type") == 0)
    {
        // The argument is a type<T> instance, get the T instead
        ot = ot->GetSubType();
    }

    new(mem)CScriptType(ot);
}

Am I missing something?

Note: my implementation of reflection also has a "type<T>" which is bound the exact same way, and uses the same C++ object.
However, when I instantiate it, I get no crash at all.

AS version: 2.30.0 WIP, Windows 7

Advertisement

You're aqcuiring the memory to instance the type in the wrong way.

The add on library shows how to properly use a generic constructor for a value type:


static void ConstructStringGeneric(asIScriptGeneric * gen)
{
  new (gen->GetObject()) string();
}

The object at index 0 is actually the SomeClass instance, and if that's not a handle, it will be freed when the function has ended execution.

Woops... I didn't noticed that terrible detail, you're right. Thank you :)

This topic is closed to new replies.

Advertisement