Jump to content
  • Advertisement
Sign in to follow this  
Droid_999

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

This topic is 896 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
Advertisement

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;

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


Only needed two small changes to work.

 

Sorry about that. It was a quick copy-and-paste from some test code that I have and I apparently didn't clean it up properly.

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!