I am making an RTS game where the script can get an array of units from the application, and select one of them as a target to shoot at.
The function to do this is registered like:
se->RegisterObjectMethod("Entity", "Entity@[]@ getAttackableEnemies()", asMETHOD(Entity,getAttackableEnemies), asCALL_THISCALL);
... and this is implemented by filling a CScriptArray of the type given by:
se->GetTypeIdByDecl("array<Entity@>")
... and the script uses it like this:
Entity@[] enemies = getAttackableEnemies();
The class itself is registered like:
se->RegisterObjectType("Entity", 0, asOBJ_REF);
se->RegisterObjectBehaviour("Entity", asBEHAVE_ADDREF, "void f()", asMETHOD(Entity,AddRef), asCALL_THISCALL);
se->RegisterObjectBehaviour("Entity", asBEHAVE_RELEASE, "void f()", asMETHOD(Entity,Release), asCALL_THISCALL);
The AddRef and Release functions do nothing.
I have been using this on 64-bit Linux for many weeks with no problems, but now on every other platform that I'm trying to port it to (lin32, win32, mac64) it crashes with the failed assertion:
as_gc.cpp:273: void asCGarbageCollector::GetStatistics(asUINT*, asUINT*, asUINT*, asUINT*, asUINT*) const: Assertion `numAdded == gcNewObjects.GetLength() + gcOldObjects.GetLength() + numDestroyed' failed
I have also floundered around trying various other combinations such as registering the function signature as Entity@[]&, or making the script use Entity@[]@ with not much improvement. This is all very similar to a question I asked a while ago here, but obviously I did not completely understand the reason for the solution then, so I am sheepishly returning here again....
In that previous question, the object type was a wrapper for the real C++ class, and was registered with asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS and the script was allowed to instantiate it. I guess I could rewrite everything to do it that way again, but I was wondering if there is something I'm missing with this function registration that would let the script have a direct handle on the C++ class.