typedef void (*AiProcPtr) (int);
//...
AiProcPtr getBehaviorPointer(Omonster* obj) {
return AiProcPtr((*(unsigned int*)obj) & 0x7FFFFFFF); //the property is at offset zero within the Omonster class
}
void setBehaviorPointerToASFunc(unsigned int func, Omonster* obj) {
obj->procPtr = (AiProcPtr)(func | 0x80000000); //the top bit is used to identify the pointer as pointing to an AngelScript function, not a native application function. it's irrelevant here.
}
//...
ASengine->RegisterObjectType("jjOBJ", sizeof(Omonster), asOBJ_REF | asOBJ_NOCOUNT );
ASengine->RegisterFuncdef("void jjBEHAVIOR(jjOBJ@)");
ASengine->RegisterObjectMethod("jjOBJ", "jjBEHAVIOR@ getBehavior()", asFUNCTION(getBehaviorPointer), asCALL_CDECL_OBJLAST);
ASengine->RegisterObjectMethod("jjOBJ", "void setBehavior(jjBEHAVIOR@)", asFUNCTIONPR(setBehaviorPointerToASFunc, (unsigned int, Omonster*), void), asCALL_CDECL_OBJLAST);
Relevant AngelScript code:
void TriggerableBlock(jjOBJ@ obj) {
}
//...
void checkBehavior() {
jjOBJ@ foo = jjObjects[1]; //indexed property accessor that returns a jjOBJ/Omonster
if (foo.getBehavior() is null) foo.setBehavior(TriggerableBlock);
}
The seventh time or so that checkBehavior() is called from within the application, the application totally crashes, having tried to read memory from an address either much too small or much too large. Depending on the context getBehavior() is called in -- a global asIScriptContext*, one created just for calling that one AngelScript function that one time, whatever -- sometimes it'll only take four calls to getBehavior() or even just one, but it's seven or eight in this particular context. The crashing does not occur if getBehavior() returns 0, but it does for all other numbers. I get similar results with a simple application function to return a constant number, e.g. 7, treated by AngelScript as returning a funcdef. getBehavior() does work, though, prior to the crash... after foo.setBehavior(TriggerableBlock); is used, (foo.getBehavior() is TriggerableBlock) evaluates to true.So what am I doing wrong? How do I get a function to return a funcdef, without everything crashing? As far as I can tell from debug information, the crash sometimes takes place somewhere in asCContext::Prepare(asIScriptFunction *func), somewhere around m_initialFunction->AddRef();. Other times it seems to happen while calling getBehavior(). I really don't know what's going on.
Sidenote: If I name the function set_behavior instead of setBehavior, I can have overloaded set_behavior functions written as functions, but AngelScript refuses to let me use them as property accessors? foo.set_behavior(TriggerableBlock); is fine but foo.behavior = TriggerableBlock; gives a compilation error. Accessors can't be overloaded?