Sign in to follow this  
chewbakka

Casting with generic call conv

Recommended Posts

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.

[CODE]
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 );
[/CODE]

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.

Share this post


Link to post
Share on other sites
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 [url="http://www.angelcode.com/angelscript/sdk/docs/manual/doc_addon_autowrap.html"]autowrapper add-on[/url] (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:

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

Where refCast is implemented as [url="http://www.angelcode.com/angelscript/sdk/docs/manual/doc_adv_class_hierarchy.html"]described in the manual[/url].

Regards,
Andreas

Share this post


Link to post
Share on other sites
I'm using 2.20.2.


[CODE]
{
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 );
}
[/CODE]

Where

[CODE]
#define _DefineFunctionWrapper( m ) struct local { asDECLARE_FUNCTION_WRAPPER( Wrapper, m ); };
[/CODE]


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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
A very simple code:

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

[size="2"]gives the error before on android.[/size]

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
With

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

I get

D:/Work/Coding/Greek/code/Engine/../CommonHeaders/../Common/../Scripting/Scriptable.h:732: error: expected primary-expression before ')' token

Share this post


Link to post
Share on other sites
Can you try replacing the macros at the end of add_on/autowrapper/aswrappedcall.h with the following:

[code]


#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>))
[/code]

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.

Share this post


Link to post
Share on other sites
I actualy added 3 macros:

[CODE]
#define WRAP_FNT(name) (::gw::id(name).template f< name >())
#define WRAP_MFNT(ClassType, name) (::gw::id(&ClassType::name).template f< &ClassType::name >())
#define WRAP_OBJ_LASTT(name) (::gw::id(name).template ol< name >())
[/CODE]

WRAP_FNT is used when registering static class functions. For some reason I don't really understand right now I have to use WRAP_MFNT for my AddRef and Release functions. And WRAP_OBJ_LASTT for my constructors, what are basically static class functions, so that is sensible.

Also I had to modify as_config.h, moving the ANDROID block on top of the __linux__ block, ans android is a linux so the android is getting detected as a linux with ARM, which is true, but still not what you expect :)

Right now my framework runs on ANDROID with generic, and on PC with native. Generic on PC is crashing, but I think it is my bad, as it is crashing only on a specific function.

Share this post


Link to post
Share on other sites
Thanks for confirming that the solution works. I'll make the necessary changes to the header and check in the code.


There was no need to add the new macros. They do exactly the same thing as the existing ones.

A static class method, is really just a global function, except it is declared in the scope of the class, that is why you need to use WRAP_FN for them.

The AddRef and Release methods are real class methods, which is why they need WRAP_MFN ([b]M[/b]ember [b]F[/b]unctio[b]N[/b]).


I'll update the as_config.h like you indicated. Thanks for that info too.

Share this post


Link to post
Share on other sites
I know when what WRAP_FN, WRAP_MFN and static functions mean. The solution is to use WRAP_FNT only for the AddRef and Release functions. They are common nonvirtual member functions. But there are other common nonvirtual member functions I've registered as well, but I only need to use WRAP_FNT for this two. Maybe because it has no parameters, nor a return value, or because they are not virtual. I don't know why I need to use it for this two.
I'll let you know when I figure it out.

Share this post


Link to post
Share on other sites
I've checked in the changes in revision 1284.

Let me know if you find something else that needs to be modified to work properly on Android. In fact, have you tested it without the wrappers, i.e. with native calling conventions? As far as I know native calling conventions should be working on Android too, though I don't have an environment to really test this for myself.

Share this post


Link to post
Share on other sites
The code change didn't work on Linux with gnuc so I had to make further changes to include the template keyword only on ANDROID.

Can you verify if the code in revision 1285 works for you on Android?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this