hi there,
i'm trying to integrate angelscript into my robot simulation I'm doing as a project for school. When i try to use a function with cdecl my app crashes with a segfault. Generic works however. I'm propably doing something quite stupid ...
here's my code:
RobotScript::RobotScript()
{
engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
if( engine == 0 )
{
cout << "Failed to create script engine." << endl;
}
// The script compiler will write any compiler messages to the callback.
engine->SetMessageCallback(asFUNCTION(MessageCallback), 0, asCALL_CDECL);
if( !strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") )
{
cout << "a" << endl;
RegisterScriptString(engine);
engine->RegisterGlobalFunction("void printText(int &in)", asFUNCTION(printText_Generic), asCALL_GENERIC);
engine->RegisterGlobalFunction("void printNumber(int &in)", asFUNCTION(printNumber), asCALL_CDECL);
}
else
{
cout << "b" << endl;
}
}
RobotScript::~RobotScript()
{
// Release the engine
engine->Release();
}
void RobotScript::addFunction(string code)
{
engine->AddScriptSection(0, "test", code.c_str(), code.size());
if (engine->Build(0) < 0)
{
cout << "couldnt compile" << endl;
}
cout << "Source added" << endl;
}
int RobotScript::runFunction(string id)
{
ctx = engine->CreateContext();
int funcId = engine->GetFunctionIDByDecl(0, id.c_str());
if (funcId < 0)
{
cout << "Function not found" << endl;
return -2;
}
int r = ctx->Prepare(funcId);
if( r < 0 )
{
cout << "Failed to prepare the context." << endl;
ctx->Release();
return -1;
}
cout << "Executing:" << endl;
r = ctx->Execute();
if( r != asEXECUTION_FINISHED )
{
// The execution didn't finish as we had planned. Determine why.
if( r == asEXECUTION_ABORTED )
cout << "The script was aborted before it could finish. Probably it timed out." << endl;
else if( r == asEXECUTION_EXCEPTION )
{
cout << "The script ended with an exception." << endl;
// Write some information about the script exception
int funcID = ctx->GetExceptionFunction();
cout << "func: " << engine->GetFunctionDeclaration(funcID) << endl;
cout << "modl: " << engine->GetFunctionModule(funcID) << endl;
cout << "sect: " << engine->GetFunctionSection(funcID) << endl;
cout << "line: " << ctx->GetExceptionLineNumber() << endl;
cout << "desc: " << ctx->GetExceptionString() << endl;
}
else
cout << "The script ended for some unforeseen reason (" << r << ")." << endl;
}
else
{
// Retrieve the return value from the context
//float returnValue = ctx->GetReturnFloat();
//cout << "The script function returned: " << returnValue << endl;
}
ctx->Release();
return 0;
}
void RobotScript::deleteFunction(string id)
{
/// \todo 1 implement this
}
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 printText(string &text)
{
cout << "Script: "<< text << endl;
}
void printText()
{
cout << "Script works ... " << endl;
}
// Function implementation with generic script interface
void printText_Generic(asIScriptGeneric *gen)
{
int *str = (int*)gen->GetArgAddress(0);
cout << "blub" << *str<< endl;
}
void printNumber(int &zahl)
{
cout << "Script: " << zahl << endl;
}
the segmentation fault occurs at this place acording to gdb:
asm("pushl %ecx \n"
"movl 12(%ebp), %ecx \n" // paramSize
"movl 8(%ebp), %eax \n" // args
"addl %ecx, %eax \n" // push arguments on the stack
"cmp $0, %ecx \n"
"je endcopy \n"
"copyloop: \n"
"subl $4, %eax \n"
"pushl (%eax) \n"
"subl $4, %ecx \n"
"jne copyloop \n"
"endcopy: \n"
"call *16(%ebp) \n"
"addl 12(%ebp), %esp \n" // pop arguments
"popl %ecx \n");
in this function: void CallCDeclFunction(const asDWORD *args, int paramSize, size_t func)
I'm using CCux-linux, which is a i686 optimised distribution running on athlon XP prozessor. compiler flaggs are: -march=i686 -pipe -fomit-frame-pointer
if any other informations could help you please don't hesitate to ask.
cu and thanks for your time
Simon