Returning classes without members

Started by
7 comments, last by Dentoid 18 years, 8 months ago
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
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

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:
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);
It does so have members. It has an operator= and two data members!
Yes, but it does not have any methods registered to AngelScript which is what Dentoid means by "no members".

-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.

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
Confirmed now that it works if I register PlayerID with asOBJ_CLASS_A. Thanks a bunch!

This topic is closed to new replies.

Advertisement