The following is a short summary of the code that crashes angelscript in 4.7.1 but not in 4.4.1:
struct A {
A() {}
static void Constructor(A *self) {new(self) A();}
static void Destructor(A *memory) {memory->~A();}
std::string getText() {return this->text;}
std::string text;
A getA() {return A();}
};
____Code run in Angelscript____:
void main() {
A a;
string text = a.getA().getText();
}
I have appended a full runnable example below since it might just be that I am registering things in the wrong way (lets hope so).
It appears to be the case that running a function that returns text from an object that was created within angelscript causes a crash.
#include <angelscript.h>
#include <add_on/scriptstdstring/scriptstdstring.h>
#include <add_on/scriptbuilder/scriptbuilder.h>
#include <stdio.h>
#include <assert.h>
#include <iostream>
void MessageCallback(const asSMessageInfo *msg, void *param) {
const char *type = "ERR ";
if( msg->type == asMSGTYPE_WARNING )
type = "WARN";
else if( msg->type == asMSGTYPE_INFORMATION )
type = "INFO";
printf("%s (%d, %d) : %s : %s\n", msg->section, msg->row, msg->col, type, msg->message);
}
void print(const std::string &in) {
std::cout << in << std::endl;
}
struct A {
A() {}
static void Constructor(A *self) {new(self) A();}
static void Destructor(A *memory) {memory->~A();}
std::string getText() {return this->text;}
std::string text;
A getA() {return A();}
};
void registerA(asIScriptEngine *engine) {
std::string name = "A";
int r = engine->RegisterObjectType(name.c_str(), sizeof(A), asOBJ_VALUE | asOBJ_APP_CLASS | asOBJ_APP_CLASS_CONSTRUCTOR); assert( r >= 0 );
r = engine->RegisterObjectBehaviour(name.c_str(), asBEHAVE_CONSTRUCT, std::string("void f()").c_str(), asFUNCTION(A::Constructor), asCALL_CDECL_OBJLAST); assert( r >= 0 );
r = engine->RegisterObjectBehaviour(name.c_str(), asBEHAVE_DESTRUCT, "void f()", asFUNCTION(A::Destructor), asCALL_CDECL_OBJLAST); assert( r >= 0 );
r = engine->RegisterObjectMethod("A", "string getText()", asMETHOD(A,getText), asCALL_THISCALL);assert( r >= 0 );
r = engine->RegisterObjectMethod("A", "A getA()", asMETHOD(A,getA), asCALL_THISCALL);assert( r >= 0 );
}
std::string app = "void main() {A a;string text = a.getA().getText();}";
int main() {
asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
int r = engine->SetMessageCallback(asFUNCTION(MessageCallback), 0, asCALL_CDECL); assert( r >= 0 );
RegisterStdString(engine);
r = engine->RegisterGlobalFunction("void print(const string &in)", asFUNCTION(print), asCALL_CDECL); assert( r >= 0 );
registerA(engine);
CScriptBuilder builder;
r = builder.StartNewModule(engine, "MyModule"); if( r < 0 ) {printf("Unrecoverable error while starting a new module.\n");return 0;}
r = builder.AddSectionFromMemory("TestSection", app.c_str());if( r < 0 ) {printf("Please correct the errors in the script and try again.\n");return 0;}
r = builder.BuildModule(); if( r < 0 ) {printf("Please correct the errors in the script and try again.\n");return 0;}
asIScriptModule *mod = engine->GetModule("MyModule");
asIScriptFunction *func = mod->GetFunctionByDecl("void main()"); if( func == 0 ) {printf("The script must have the function 'void main()'. Please add it and try again.\n");return 0;}
asIScriptContext *ctx = engine->CreateContext();
ctx->Prepare(func);
r = ctx->Execute(); if( r != asEXECUTION_FINISHED and r == asEXECUTION_EXCEPTION) {printf("An exception '%s' occurred. Please correct the code and try again.\n", ctx->GetExceptionString());}
}