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

Using the "string" script class with "char*" parameters?

Started by
9 comments, last by Jedive 18 years, 10 months ago
Hello guys. Sorry if this has been asked before, but the "search" feature of the forums is disabled. I have exported a bunch of global functions to AngelScript, to make my application scriptable. Some of these functions have a "const char*" style string as parameter, others have a "const char*" string as return value. I have registered the "string" data type in my virtual machine, using the "scriptstring" addon in the AngelScript 2.1.0c package. The problem is that when I try to call one of the functions that need / return a string, the program crashes. I think that this is because the "scriptstring" addon uses a std::string as the "string" type, instad of an array of chars. Do you guys know of a version of the "scriptstring" addon which is compatible with "char*" style strings? Thanks.
Advertisement
Pointers are not available in the current stable build of AS. If you need char*, try registering the std:string c_str() function and try that.
The char* strings are not very script friendly, since their life time cannot be determined. I suggest that you make a simple wrapper for your functions that take char*. E.g:

void func(const char *);// std::string& is compatible with asCScriptString&void wrapper_func(std::string &str){  func(str.c_str());}


Register the wrapper function like this:

engine->RegisterGlobalFunction("void func(string ∈)", asFUNCTION(wrapper_func), asCALL_CDECL);


You can do the same for functions that return a const char*. Just have them allocate a new asCScriptString and return that one as a object handle. Example:

const char *func();asCScriptString *wrapper_func(){  asCScriptString *str = new asCScriptString();  str->buffer = func();  return str;}engine->RegisterGlobalFunction("string @func()", asFUNCTION(wrapper_func), asCALL_CDECL);


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

Thanks for your help. I have written wrappers for all the functions that receive or return strings, and now it works perfectly. Thank you very much!
it is good that use wrap function, but sometimes we can't do this.
such as:
if we have a class,we want expose it to script,we can not add wrap method because it will change the object's memory layout.
so what can we do?
You can do a couple of different things. You wrap the entire class in another class, take a look at asCScriptString in the add_on directory for an example of this.

You can also register global functions as if they were methods on the class, e.g.:

void ExtraMethod(int param, MyObject *obj){  // Do something with the object}engine->RegisterObjectMethod("MyObject", "void ExtraMethod(int)", asFUNCTION(ExtraMethod), asCALL_CDECL_OBJLAST);


To the scripts this ExtraMethod() will not look any different than any other method registered for the type.

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

Hey WitchLord, I can't make things work as you told me before. I was doing something wrong. When I registered a function, I did it this way:

void csDeviceCaption_STR(std::string caption){   csDeviceCaption(caption.c_str());}engine->RegisterGlobalFunction("void DeviceCaption(string caption)", asFUNCTION(csDeviceCaption_STR), asCALL_CDECL)


But this has lead me into problems with the stack when receiving parameters. I am doing this because registering the function in the way you told gives me an error:

void csDeviceCaption_STR(std::string &caption){   csDeviceCaption(caption.c_str());}engine->RegisterGlobalFunction("void DeviceCaption(string &caption)", asFUNCTION(csDeviceCaption_STR), asCALL_CDECL)


Here, RegisterGlobalFunction() returns a negative value, so the function has not been registered properly :(

Do you know what's wrong?
You have to register it like this:

engine->RegisterGlobalFunction("void DeviceCaption(string ∈ caption)", asFUNCTION(csDeviceCaption_STR), asCALL_CDECL)


And have your C++ Function:

void csDeviceCaption_STR(std::string &caption)
{
csDeviceCaption(caption.c_str());
}
I see a lot of people being bitten by the in/out thing. We might need a sticky with a title such as 'Having trouble with refrences?'.
Jedive:

Rain Dog is correct. AngelScript requires that all parameter references be marked with one of in, out, or inout.

Deyja:

Yeah.

I have taken steps to correct this for the next WIP of 2.4.0, I hope. The message stream will now be set on the engine directly after creating it, allowing the register functions to write error messages as well. Hopefully this will help people understand what is wrong.



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