Jump to content
  • Advertisement
Sign in to follow this  
Jedive

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

This topic is 4831 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

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.

Share this post


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

Share this post


Link to post
Share on other sites
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 &in)", 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

Share this post


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

Share this post


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

Share this post


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

Share this post


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

Share this post


Link to post
Share on other sites
You have to register it like this:

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


And have your C++ Function:

void csDeviceCaption_STR(std::string &caption)
{
csDeviceCaption(caption.c_str());
}

Share this post


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

Share this post


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



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!