Sign in to follow this  

Newbie: How do I pass a std::string to a scripted function

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

Hi

 

A very basic question that has had me stumped all day.  First up, I'm not a c++ person, just plain C, so all the object oriented stuff is beyond me.  I do have Angelscript working with my game engine, and I can call scripts from the host, and call C functions from the scripts - all working fine.

 

I now have a need to pass a std::string type from the host program to the script.

 

The script is written like this


// This function is called when a object is clicked
void as_guiHandleButtonPress(string &in objectID)
//------------------------------------------------------------
{
    sys_printConStr(objectID, "");


            if (objectID == "buttonStartGame")
            {
                currentMode = MODE_GAME;
            }}

I can create the function mapping ok - I get a valid ID back ( this from my logfile )

scriptFunctions [ void as_guiHandleButtonPress(string &in) ] has ID [ 44977616 ]

I think my problem is here - I can't work out how to pass the string as a parameter:

 

    if (scriptFunctions[i].param1 == true)
    {
        string testParam;
        strcpy(testParam.c_str(), funcParam);   // Convert from char to string type


        io_logToFile("Parameter to pass to script [ %s ]", testParam.c_str());
        // Has the right string "buttonStartGame"
        context->SetArgObject(0, &testParam);
    }

 

This is my output

Parameter to pass to script [ buttonStartGame ]
[  ] [  ]

Any advice would be welcomed.

 

Thanks.

Edited by Droid_999

Share this post


Link to post
Share on other sites

The problem here is that your script function is expecting a reference to the string, i.e. "string &in objectID". Because of that you need to make sure the string that you're passing to the function stays alive through-out the execution of the script function.

 

Declare the testParam variable at a higher scope so you know it will stay alive long enough, and everything should work. :)

Share this post


Link to post
Share on other sites


Declare the testParam variable at a higher scope so you know it will stay alive long enough, and everything should work

 

Thanks - tried that - still nothing. testParam is now global so should be good to go.

 

How can I debug a script to see if the value it actually being passed into the function?

Share this post


Link to post
Share on other sites

 

You're copying the string into std::string's buffer incorrectly. What you're doing can result in illegal memory access and/or corrupted object state in the string object. Use assignment here:

testParam = funcParam;

 

Hah, I totally missed that. 

 

 


How can I debug a script to see if the value it actually being passed into the function?

 

 

If you want to implement an interactive debugger, you can do so by building upon the Debugger add-on, or try the asPEEK third party debugger

 

However, if you just want to check the value of the parameters as seen from the script, you can do so by enumerating the variables using the methods on the asIScriptContext interface, i.e. GetVarCount, GetVarName, GetAddressOfVar, etc.

 

You could for example, implement a simple function that prints all the local variables and their values, register it with the script engine, and then call it from the script where you wish to inspect the values.

 

void PrintVariables()
{
  asIScriptContext *ctx = asGetActiveContext();
  asIScriptEngine *engine = ctx->GetEngine();
 
  int typeId = ctx->GetThisTypeId();
  void *varPointer = ctx->GetThisPointer();
  if( typeId )
  {
    print(" this = 0x%x\n", varPointer);
  }
 
  int numVars = ctx->GetVarCount();
  for( int n = 0; n < numVars; n++ )
  {
    int typeId = ctx->GetVarTypeId(n); 
    void *varPointer = ctx->GetAddressOfVar(n);
    if( typeId == engine->GetTypeIdByDecl("int") )
    {
      print(" %s = %d\n", ctx->GetVarDeclaration(n, stackLevel), *(int*)varPointer);
    }
    else if( typeId == engine->GetTypeIdByDecl("string") )
    {
      std::string *str = (std::string*)varPointer;
      if( str )
        print(" %s = '%s'\n", ctx->GetVarDeclaration(n, stackLevel), str->buffer.c_str());
      else
        print(" %s = <null>\n", ctx->GetVarDeclaration(n, stackLevel));
    }
    else
    {
      print(" %s = {...}\n", ctx->GetVarDeclaration(n, stackLevel));
    }
  }
}

Share this post


Link to post
Share on other sites

 

You're copying the string into std::string's buffer incorrectly. What you're doing can result in illegal memory access and/or corrupted object state in the string object. Use assignment here:

testParam = funcParam;

 

That was it.  I thought because I was passing in a char * that it would need to be copied into std::string.c_str().  All works now.

 

I have also implemented the above code to display the variables as they run from the script.  Only needed two small changes to work.

 

stackLevel wasn't declared, and this line

print(" %s = '%s'\n", ctx->GetVarDeclaration(n, stackLevel), str->buffer.c_str());

became this 

print(" %s = '%s'\n", ctx->GetVarDeclaration(n, stackLevel), str->c_str());

I was getting 

error: 'std::__cxx11::string {aka class std::__cxx11::basic_string<char>}' has no member named 'buffer'

Thanks for your help.

Share this post


Link to post
Share on other sites

This topic is 680 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this