Jump to content
  • Advertisement
Sign in to follow this  
Dentoid

Returning classes without members

This topic is 4843 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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

Share this post


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

Share this post


Link to post
Share on other sites
The PlayerID class looks like this:

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);

Share this post


Link to post
Share on other sites
Irrelevant. C++ is returning the object, not angelscript. It should have no effect. The fact that it does is the problem.

Share this post


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

Share this post


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

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!