🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

member function returns invalid object

Started by
6 comments, last by wolfeinstein 18 years, 5 months ago
Little changed from my previous example. It crashes. It shouldn't. The crash actually occurs on line 1677 of as_context.cpp. /*snip*/ [Edited by - Deyja on January 16, 2006 12:24:50 PM]
Advertisement
Is this with the released version of 2.5.0 or the WIP?
I'm guessing it is with the WIP, since the post was made before I uploaded the release version.

I'll look into this.

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

And I'll see if the final fixes it. :)

It doesn't. :(

Anyway; calling the function doesn't crash. Trying to assign the value to anything does. :/

[Edited by - Deyja on January 16, 2006 12:04:11 PM]
@&#%^@! I had the old version on my clipboard...

THIS one crashes... *whistle*
#include "angelscript.h"#include <string>#include <iostream>struct Foo {	Foo() {}	~Foo() {}	Foo(const Foo& rhs) {}	Foo& operator=(const Foo& rhs) { return *this; }};std::string foo_member_fun_one(const std::string& in, Foo* thisp){	std::cout << "foo_member_fun_one: " << in << "\n";	return in;}void foo_member_fun_two(const std::string& in, Foo* thisp){	std::cout << "foo_member_fun_two: " << in << "\n";}std::string free_fun(const std::string& in){	std::cout << "free_fun: " << in << "\n";	return in;}void ConstructFoo(Foo* ptr) { new (ptr) Foo(); }void CopyConstructFoo(const Foo& rhs, Foo* ptr) { new (ptr) Foo(rhs); }void DestroyFoo(Foo* ptr) { ptr->~Foo(); } Foo& AssignFoo(const Foo& rhs, Foo* ptr) { return (*ptr) = rhs; }void ConstructString(std::string* ptr) { new (ptr) std::string(); }void CopyConstructString(const std::string& rhs, std::string* ptr) { new (ptr) std::string(rhs); }void DestroyString(std::string* ptr) { ptr->~basic_string(); } std::string& AssignString(const std::string& rhs, std::string* ptr) { return (*ptr) = rhs; }void print(std::string* thisp){	std::cout << "String member print. " << thisp->size() << "\n";}std::string StringFactory(unsigned int length, const char *s)	{		std::cout << "StringFactory: " << std::string(s,length) << "\n";		return std::string(s,length);	}int main(int argc, char* argv[]){	asIScriptEngine* engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);	int error_code = 0;		std::cout << "Registering Foo. ";	error_code = engine->RegisterObjectType("Foo",sizeof(Foo),asOBJ_CLASS_CDA);	if (error_code < 0) std::cout << "Error: " << error_code;	std::cout << "\nRegistering Foo constructor. ";	error_code = engine->RegisterObjectBehaviour("Foo",		asBEHAVE_CONSTRUCT,		"void constructor()",		asFUNCTION(ConstructFoo),		asCALL_CDECL_OBJLAST);		if (error_code < 0) std::cout << "Error: " << error_code;	std::cout << "\nRegistering Foo destructor. ";		error_code = engine->RegisterObjectBehaviour("Foo",		asBEHAVE_DESTRUCT,		"void destructor()",		asFUNCTION(DestroyFoo),		asCALL_CDECL_OBJLAST);		if (error_code < 0) std::cout << "Error: " << error_code;	std::cout << "\nRegistering Foo operator=. ";	error_code = engine->RegisterObjectBehaviour("Foo",		asBEHAVE_ASSIGNMENT,		"Foo& op_assign(const Foo&)",		asFUNCTION(AssignFoo),		asCALL_CDECL_OBJLAST);		if (error_code < 0) std::cout << "Error: " << error_code;	std::cout << "\nRegistering Foo copy constructor. ";	error_code = engine->RegisterObjectBehaviour("Foo",		asBEHAVE_CONSTRUCT,		"void constructor(const Foo&)",		asFUNCTION(CopyConstructFoo),		asCALL_CDECL_OBJLAST);						if (error_code < 0) std::cout << "Error: " << error_code;	std::cout << "\nRegistering string. ";	error_code = engine->RegisterObjectType("string",sizeof(std::string),asOBJ_CLASS_CDA);	if (error_code < 0) std::cout << "Error: " << error_code;	std::cout << "\nRegistering string constructor. ";	error_code = engine->RegisterObjectBehaviour("string",		asBEHAVE_CONSTRUCT,		"void constructor()",		asFUNCTION(ConstructString),		asCALL_CDECL_OBJLAST);		if (error_code < 0) std::cout << "Error: " << error_code;	std::cout << "\nRegistering string destructor. ";		error_code = engine->RegisterObjectBehaviour("string",		asBEHAVE_DESTRUCT,		"void destructor()",		asFUNCTION(DestroyString),		asCALL_CDECL_OBJLAST);		if (error_code < 0) std::cout << "Error: " << error_code;	std::cout << "\nRegistering string operator=. ";	error_code = engine->RegisterObjectBehaviour("string",		asBEHAVE_ASSIGNMENT,		"string& op_assign(const string&)",		asFUNCTION(AssignString),		asCALL_CDECL_OBJLAST);		if (error_code < 0) std::cout << "Error: " << error_code;	std::cout << "\nRegistering string copy constructor. ";	error_code = engine->RegisterObjectBehaviour("string",		asBEHAVE_CONSTRUCT,		"void constructor(const string&)",		asFUNCTION(CopyConstructString),		asCALL_CDECL_OBJLAST);						if (error_code < 0) std::cout << "Error: " << error_code;	std::cout << "\nRegistering string factory. ";	error_code = engine->RegisterStringFactory("string",		asFUNCTION(StringFactory),		asCALL_CDECL);	if (error_code < 0) std::cout << "Error: " << error_code;	std::cout << "\nRegistering Foo member fun one. ";	error_code = engine->RegisterObjectMethod("Foo",		"string member_one(const string&)",		asFUNCTION(foo_member_fun_one),		asCALL_CDECL_OBJLAST);	if (error_code < 0) std::cout << "Error: " << error_code;	std::cout << "\nRegistering Foo member fun two. ";	error_code = engine->RegisterObjectMethod("Foo",		"void member_two(const string&)",		asFUNCTION(foo_member_fun_two),		asCALL_CDECL_OBJLAST);	if (error_code < 0) std::cout << "Error: " << error_code;	std::cout << "\nRegistering free fun. ";	error_code = engine->RegisterGlobalFunction(		"string free_fun(const string&)",		asFUNCTION(free_fun),		asCALL_CDECL);	if (error_code < 0) std::cout << "Error: " << error_code;	std::cout << "\nRegistering string print member fun. ";	error_code = engine->RegisterObjectMethod("string",		"void print()",		asFUNCTION(print),		asCALL_CDECL_OBJLAST);	if (error_code < 0) std::cout << "Error: " << error_code;	std::string script = "void test(Foo f) { string r; r = f.member_one(\"foo\"); }";	engine->AddScriptSection(0,"test",script.c_str(),script.length());		std::cout << "\nBuilding test script. ";	error_code = engine->Build(0);	if (error_code < 0) std::cout << "Error: " << error_code;	std::cout << "\nGetting function id. ";	int func_id = engine->GetFunctionIDByName(0,"test");	if (func_id < 0) std::cout << error_code;	asIScriptContext* ctx = engine->CreateContext();	std::cout << "\nPreparing context. ";	error_code = ctx->Prepare(func_id);	if (error_code < 0) std::cout << "Error: " << error_code;	Foo f;	std::cout << "\nSetting parameter. ";	error_code = ctx->SetArgObject(0,&f);	if (error_code < 0) std::cout << "Error: " << error_code;	std::cout << "\nCalling script.\n";	error_code = ctx->Execute();	if (error_code != asEXECUTION_FINISHED) std::cout << "Error: " << error_code;	std::cout << "\n\nFin.";		return 0;}
I'm also had stuck with this problem.
It occuers in both release and WIP's of 2.5.0 version and can be reproduced in more simple way:

void Test(){ FuncCrash("test");}void FuncCrash(const string &in str){ //nothing to do}


String "test" creates succesfully (call to CallSystemFunction->CallCDeclFunctionQWord->StringFactory(asUINT, const char*)).
Returned value (retQW) from CallCDeclFunctionQWord is valid and points to currently allocated asCScriptString class.

After this in ExecuteNext loop it stores returned pointer
*(l_fp - SWORDARG0(l_bc)) = asDWORD(objectRegister);
and BC_ChkNullV check "that" stored in pointer and got "0" and raises exception TXT_NULL_POINTER_ACCESS.

I'm not sure ChkNullV uses right way:
...
asDWORD *a = *(asDWORD**)(l_fp - SWORDARG0(l_bc));
if( *a == 0 )
...

Maybe here were assumed "if(a == 0)" as check for NULL pointer?
Cause "*a" is a pointer to internal data of object. And of cause first byte of object can easily be zero.
Game programmer.DirectX9, OpenGL.
Deyja:

I've been able to confirm and fix the bug that you discovered. I'll release an update to 2.5.0 this weekend I hope. In the meantime I believe you can work around the problem by using const string ∈ for the assignment operator, instead of just const

wolfenstein:

I've not been able to confirm your problem. But it is entirely possible that the fix I applied for Deyja's problem also corrected this one. Let me know as soon as you have the new version if the problem remains.

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

Not sure, but maybe my problem appears only in the VS2005 compiler?
I'm using VS2005 in the project and regrettably can't switch back to VS2003.
I'll wait for update and then will try tests in both compilers to find workaround. Currently switching back to 2.4.1d
Game programmer.DirectX9, OpenGL.

This topic is closed to new replies.

Advertisement