🎉 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!

Strings, passing to native functions and converting from math types

Started by
12 comments, last by WitchLord 19 years, 5 months ago
Hi, I'm having some problems with strings. I'm using this code:

void print_str(std::string msg)
{
//	std::cout << msg << std::endl;
	printf("%s\n", msg.c_str());
}

void print_int(int i)
{
//	std::cout << i << std::endl;
	printf("%d\n", i);
}

const char * script = 
"								"
"	void do_test()					"
"	{							"
"		int i = 42;					"
"		print_int(i);					"
"								"
"		string msg = \"Hello, World!\";		"
"		print_str(msg);				"
"	}							"
"								";

int main()
{
 	asIScriptEngine * engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);

	RegisterStdString(engine);

	engine->RegisterGlobalFunction("void print_str(string msg)", asFUNCTION(print_str), asCALL_CDECL);
	engine->RegisterGlobalFunction("void print_int(int i)", asFUNCTION(print_int), asCALL_CDECL);

	OutStream out;
	engine->AddScriptSection(0, "name", script, (int)strlen(script), 0);
	engine->Build(0, &out);

	asIScriptContext *ctx;
	engine->CreateContext(&ctx);
	ctx->Prepare(engine->GetFunctionIDByDecl(0, "void do_test()"));

	int r = ctx->Execute();
	
	if (r != 0)
	{
		if (r == asEXECUTION_EXCEPTION)
		{
			printf("Script exception\n");
			printf("Func: %s\n", engine->GetFunctionName(ctx->GetExceptionFunction()));
			printf("Line: %d\n", ctx->GetExceptionLineNumber());
			printf("Desc: %s\n", ctx->GetExceptionString());
		}
	}

	return 0;
}



Which prints the int as expected, but doesn't print the string. I put a breakpoint in print_str and msg is empty. Any ideas? Secondly, I want to be able to convert between the math types and strings in script as if it were a typeless language. I think to do this I just need to register asBEHAVE_ASSIGNMENT functions for "string &f(int ∈)" (and other types as needed), and then implement the conversion function as something like:

string IntToString(int i)
{
	stringstream stream;
	stream << i;

	string str;
	stream >> str;

	return str;
}



Am I on the right track? Have I missed some existing functionality that does this automatically or provides a simpler way? Alan
"There will come a time when you believe everything is finished. That will be the beginning." -Louis L'Amour
Advertisement
You said the string is empty in print_str - have you checked how you are passing the string from AS to C++?

Your conversion functions is very near the cannocal lexical_cast:
template <typename R, typename T> R lexical_cast(const T& in){   stringstream str;   str << in;   R ret;   str >> ret;   return ret;}
I;m not sure about the problem with the strings in AS, everything looks normal, but your conversion routine could be simplified a bit:

std::string IntToString(int i){	std::istringstream stream;	stream << i;	return stream.str();}
Quote:
You said the string is empty in print_str - have you checked how you are passing the string from AS to C++?


I'm not exactly sure what you mean? I'm calling print_str from my as script. I put a break point into the stdstring StringFactory function, and at some point the correct string is being created. I tried changing print_str to take a reference to a string, but now I get an "Invalid configuration" error message.

As for the conversion routines, I'm pretty sure I can manage to turn an int into a string :-) My question was more todo with how to write the AS interface code, ie can I just provide an asBEHAVE_ASSIGNMENT function for strings that takes a paramter of an int and have AS to do the right thing? I would just try it, but I cant print strings to see if its working...

Alan
"There will come a time when you believe everything is finished. That will be the beginning." -Louis L'Amour
That should work. It's not like AS could handle the template anyhow.

Have you registered all of the strings operators properly?
Are you using the stable 1.10 version or the new 2.0? AFAIK; changes were made to how parameters were passed to C++ for 2.0.
Let me answer your second question first. Yes, you can register the asBEHAVE_ASSIGNMENT with different types to have the script allow automatic conversion of types to strings. You can also register asBEHAVE_ADD to allow conversion when doing concatenations as well.

Now for the first question, that is more worrying to me. There is no apparent error in your code, that leads me to believe it might be a problem with AngelScript itself. What version of AngelScript are you using, and what C++ compiler are you using? As a possible work around you might want to change the print_str() function to take a reference to the string instead of a copy of the string.

void print_str(std::string &msg){// std::cout << msg << std::endl;  printf("%s\n", msg.c_str());}engine->RegisterGlobalFunction("void print_str(string ∈)", asFUNCTION(print_str), asCALL_CDECL);


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

Thanks for the reply. I'm using Visual Studio .NET 2003, and AngelScript 2.0.0 WIP1.

To try and figure out where things were going wrong I put print statements into StringFactory, ConstructString, DestructString and print_str, and found something rather strange. (c++ style comments are my annotations).

ConstructString()  // the string gets createdStringFactory("Hello, World!")  // and filled with its contentsDestructString()   // the string gets destroyed...ConstructString()  // a new string gets createdprint_str()        // called with the new, empty string(null)         // this is the printf trying to output the contents of the stringDestructString()   // at least it doesn't leak the memory :-)


I tried the changes to calling print_str with a reference, but it now won't even Build. It just says "Invalid Configuration".

Alan
"There will come a time when you believe everything is finished. That will be the beginning." -Louis L'Amour
Seems like a bug in AS 2.0 WIP 1. I'll try to verify that as soon as possible.

Did you register the print_str() function exactly as I wrote it? with the 'string ∈' parameter? the 'in' keyword is necessary to tell the library how the reference is used.

It will be a while yet before AS 2.0 will be stable, so if you wish to work with something stable and bug free I suggest you try AS 1.10.1c instead. If you don't mind the bugs in AS 2.0 you're welcome to use it of course, it will help me find the bugs that are likely to be there.

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

Quote:
Did you register the print_str() function exactly as I wrote it? with the 'string ∈' parameter? the 'in' keyword is necessary to tell the library how the reference is used.


No I hadn't. Changing that and it works! Thanks.

In an attempt to track down the problem I grabbed a copy of 1.10.1c, which worked with the original (non-reference) version. I enabled AS_DEBUG and compared the byte code generated by both versions, and they were identical. That means the bug has to be in the interpreter, but debugging into that is a little beyond my familiarity with AS at the moment.

As a sidenote, it would make checking bytecode easier if the reference actually contained all the instructions :-)

Alan
"There will come a time when you believe everything is finished. That will be the beginning." -Louis L'Amour
It's good to hear that at least the reference version works. I'm sure I'll be able to find out pretty soon why the non-reference version fails. I'll be back tomorrow with more info on that (hopefully).

The bytecode reference actually do contain all the instructions, though you have to read the right version. The one on the site is for version 1.10.1c and the one for 2.0.0 WIP 1 can be found in the zip.

If the bytecode was identical for both versions then something is terribly wrong. AngelScript has changed substantially in the way it handles objects (strings included) that it should definitely be different from 1.10.1c.

But don't worry, with your sample code I'm sure it will be easy (for me) to find the 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

This topic is closed to new replies.

Advertisement