Returning classes without members
Hey
I have a little problem with a method returning a class. The method registration looks like this:
engine->RegisterObjectMethod ("NetworkConnection", "PlayerID GetPlayerId ()", asMETHOD(NetworkConnection, GetPlayerId), asCALL_THISCALL);
The PlayerID class is just a really simple class without members or methods. When GetPlayerId is called from the script, it results in a write access violation when the playerID is returned. (The GetPlayerId just returns a PlayerID class right away, so it's a very simple function.)
After loads of investigation of what the heck is going on, I discovered that it seemed to use the wrong CallThisCallFunctionXXXX-caller. This was because the callConv was ICC_THISCALL instead of ICC_THISCALL_RETURNINMEM. (I compared with another method I had returning another class that worked, and it had ICC_THISCALL_RETURNINMEM instead.) Further investigation showed that if I added a dummy method to PlayerID, another path was taken somewhere in the callConv-decisions, resulting in the correct callConv, and everything worked fine.
So, bottom line:
It seems like the wrong callConv is chosen on methods that return a class without members or methods. I don't dare guess what's wrong in that decision code since I'm not sure what's going on there in the first place, but I hope this is enough info for you (WitchLord) to find out what's wrong. :)
Thanks in advance!
/Anders Stenberg
I need to know what the PlayerID C++ class looks like, and how you registered it with the script engine.
The most common reason for the wrong internal calling convention is the wrong flag in the RegisterObjectType() call, e.g. asOBJ_CLASS instead of asOBJ_CLASS_CDA, etc. This flag tells the script engine exactly how C++ handles the type.
That you were able to solve the problem by registering a dummy method seems strange to me. I'll have to verify this.
Regards,
Andreas
The most common reason for the wrong internal calling convention is the wrong flag in the RegisterObjectType() call, e.g. asOBJ_CLASS instead of asOBJ_CLASS_CDA, etc. This flag tells the script engine exactly how C++ handles the type.
That you were able to solve the problem by registering a dummy method seems strange to me. I'll have to verify this.
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
The PlayerID class looks like this:
And it's registered like this:
engine->RegisterObjectType ("PlayerID", sizeof (PlayerID), asOBJ_CLASS);
No members whatsoever, as I said (but might've been a bit unclear about :).
Don't worry about the class being 6 bytes, the compiler pads it out to 8 so a sizeof returns 8. (I've tried padding out to 12 bytes too, to force it to not return in eax/edx, but that didn't help.)
The dummy I registered was just:
engine->RegisterObjectMethod ("PlayerID", "void Dummy ()", asFUNCTION(DummyFunc), asCALL_CDECL_OBJLAST);
struct PlayerID{ unsigned long binaryAddress; // From inet_addr unsigned short port; PlayerID& PlayerID::operator = (const PlayerID& input) {binaryAddress=input.binaryAddress; port=input.port; return *this;} friend int operator==(const PlayerID& left, const PlayerID& right); friend int operator!=(const PlayerID& left, const PlayerID& right); friend int operator > (const PlayerID& left, const PlayerID& right); friend int operator < (const PlayerID& left, const PlayerID& right);};
And it's registered like this:
engine->RegisterObjectType ("PlayerID", sizeof (PlayerID), asOBJ_CLASS);
No members whatsoever, as I said (but might've been a bit unclear about :).
Don't worry about the class being 6 bytes, the compiler pads it out to 8 so a sizeof returns 8. (I've tried padding out to 12 bytes too, to force it to not return in eax/edx, but that didn't help.)
The dummy I registered was just:
engine->RegisterObjectMethod ("PlayerID", "void Dummy ()", asFUNCTION(DummyFunc), asCALL_CDECL_OBJLAST);
Yes, but it does not have any methods registered to AngelScript which is what Dentoid means by "no members".
-M
-M
Irrelevant. C++ is returning the object, not angelscript. It should have no effect. The fact that it does is the problem.
The PlayerID type must be registered with the flag asOBJ_CLASS_A, since it has an assignment operator.
Using this flag AngelScript should be able to correctly determine that the type is always returned in memory by the C++ application. (I'm assuming you're using MSVC here.)
Tomorrow I'll try to determine why you got a different result by registering the dummy method. That would seem to be a bug.
Using this flag AngelScript should be able to correctly determine that the type is always returned in memory by the C++ application. (I'm assuming you're using MSVC here.)
Tomorrow I'll try to determine why you got a different result by registering the dummy method. That would seem to be a bug.
AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game
Oh, the CDA-suffixes specify if the C++ class has constructor, destructor and/or assignment? I thought it was if it has those as registered behaviours. But well, thinking about it, it makes more sense that way. :)
Thanks anyway
Thanks anyway
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement