Casting with generic call conv

Started by
13 comments, last by WitchLord 11 years, 12 months ago
Hi all,

I have my framework powered by AS up and runnig. However if I use casting behaviour with max portability, I get a nice crash.


r = engine->RegisterObjectBehaviour("base", asBEHAVE_REF_CAST, "derived@ f()", asFUNCTION(Wrapper1), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectBehaviour("derived", asBEHAVE_IMPLICIT_REF_CAST, "base@ f()", asFUNCTION(Wrapper2), asCALL_GENERIC); assert( r >= 0 );


where Wrapper1 and Wrapper2 are autowrappers to (refCast<base,derived>) and (refCast<derived,base>).

After this if I do an implicit cast in script, I get a nice crash in system function calling with the object pointer being NULL, debugged it and the object I want to cast is not NULL. With native calling everything is nice and smooth.

Is there a special way I should register casting for max portability?

Thank you.
Advertisement
Which version of AngelScript are you using?

Can you show how you declared the autowrappers?

Version 2.23.0 introduced an improved version of the autowrapper add-on (thanks to SiCrane) that eliminate the need to declare the wrapper and then register it in two separate calls. With the new version you would register it as the following:


r = engine->RegisterObjectBehaviour("base", asBEHAVE_REF_CAST, "derived@ f()", WRAP_OBJ_LAST((refCast<base,derived>)), asCALL_GENERIC); assert( r >= 0 );


Where refCast is implemented as described in the manual.

Regards,
Andreas

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

I'm using 2.20.2.



{
typedef Derived* (CastFn*)( From* );
CastFn castFn = RefCast< Base, Derived >;
_DefineFunctionWrapper( castFn );
Verify( ScriptEngine::Instance().GetAsEngine()->RegisterObjectBehaviour( baseName.GetBuffer(), asBEHAVE_REF_CAST, derivedCast.GetBuffer(), asFUNCTION( local::Wrapper ), asCALL_GENERIC ) >= 0 );
}
{
typedef Base* (CastFn*)( Derived* );
CastFn castFn = RefCast< Derived, Base >;
_DefineFunctionWrapper( castFn );
Verify( ScriptEngine::Instance().GetAsEngine()->RegisterObjectBehaviour( derivedName.GetBuffer(), asBEHAVE_IMPLICIT_REF_CAST, baseCast.GetBuffer(), asFUNCTION( local::Wrapper ), asCALL_GENERIC ) >= 0 );
}


Where


#define _DefineFunctionWrapper( m ) struct local { asDECLARE_FUNCTION_WRAPPER( Wrapper, m ); };



Done a little debugging in the meantime.

In the function asWrapNative_p1 the call gen->GetAddressOfReturnLocation() returns NULL. After that it is crashing.

In asCContext::CallGeneric, there is the initialization of gen with: asCGeneric gen(engine, sysFunction, currentObject, args);
That is basically initializing objectRegister to NULL, and later asCGeneric::GetAddressOfReturnLocation returns that.

Hope this helps.
Just upgraded to 2.23.0 and it is working now. Strange.
OK. Thanks for confirming that it is working with the latest version. :)

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Have you tried compiling the new wrapper on android.

It gives me compiling errors of:

expected primary-expression before ')' token

For almost every use of the new wrapper macros. The same code works on PC as said before.
A very simple code:


class Alma
{
public:
void Foo()
{
}
};
Verify( ScriptEngine::Instance().GetAsEngine()->RegisterObjectBehaviour( "Alma", asBEHAVE_ADDREF, "void f()", WRAP_MFN( Alma, Foo ), asCALL_GENERIC ) >= 0 );


[size="2"]gives the error before on android.
I guess the compiler for Android requires a little more aid to properly parse the template code.



Does WRAP_MFN_PR work? i.e. WRAP_MFN_PR( Alma, Foo, (), void )

Can you show the full compiler output?

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

With


class Alma
{
public:
void Foo()
{
}
};
ScriptEngine::Instance().GetAsEngine()->RegisterObjectBehaviour( "Alma", asBEHAVE_ADDREF, "void f()", WRAP_MFN_PR( Alma, Foo, (void), void ), asCALL_GENERIC );


I get

D:/Work/Coding/Greek/code/Engine/../CommonHeaders/../Common/../Scripting/Scriptable.h:732: error: expected primary-expression before ')' token
Can you try replacing the macros at the end of add_on/autowrapper/aswrappedcall.h with the following:




#define WRAP_FN(name) (::gw::id(name).template f< name >())
#define WRAP_MFN(ClassType, name) (::gw::id(&ClassType::name).template f< &ClassType::name >())
#define WRAP_OBJ_FIRST(name) (::gw::id(name).template of< name >())
#define WRAP_OBJ_LAST(name) (::gw::id(name).template ol< name >())

#define WRAP_FN_PR(name, Parameters, ReturnType) asFUNCTION((::gw::template Wrapper<ReturnType (*)Parameters>::template f< name >))
#define WRAP_MFN_PR(ClassType, name, Parameters, ReturnType) asFUNCTION((::gw::template Wrapper<ReturnType (ClassType::*)Parameters>::template f< &ClassType::name >))
#define WRAP_OBJ_FIRST_PR(name, Parameters, ReturnType) asFUNCTION((::gw::template ObjFirst<ReturnType (*)Parameters>::template f< name >))
#define WRAP_OBJ_LAST_PR(name, Parameters, ReturnType) asFUNCTION((::gw::template ObjLast<ReturnType (*)Parameters>::template f< name >))

#define WRAP_CON(ClassType, Parameters) asFUNCTION((::gw::template Constructor<ClassType Parameters>::f))
#define WRAP_DES(ClassType) asFUNCTION((::gw::template destroy<ClassType>))


The changes are the addition of the keyword 'template' in the macros. It is probably what the compiler is expecting. Some compilers manage without the keyword (like MSVC) but it seems the compiler for Android doesn't.

Hopefully this will solve the problem. If it does I'll check in these changes.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

This topic is closed to new replies.

Advertisement