Sign in to follow this  

scriptstring.h -- necessary?

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

Just a simple question... is "scriptstring.h" necessary for using strings in AngelScript, or is it merely there to illustrate adding on to the language or something like that? I sometimes run into problems when including it in a new project, and would just like to know if I can omit it. Thanks.

Share this post


Link to post
Share on other sites
scriptstring.h is an add-on, you don't have to use it. If you don't register any string type you won't be able to use strings in AngelScript, but perhaps you don't need to.

What kind of problems do you have when including scriptstring.h in your projects? Maybe it's something I can improve.

Share this post


Link to post
Share on other sites
Hi,

Sorry for occupy the thread, but I have some problems with strings and I think this thread is good place to talk :)

I need strings en my script, but I can't use std::string because I want my engine be multiplatform. That's the reason why I can't use ScriptString, I download bstr than looks useful for me, but I try to use it and I have a lot of errors:

1) Compiling error:

'RegisterTypeBehaviour' : is not a member of 'asIScriptEngine'

Looks like bstr use an old version of AngelScript. I change RegisterTypeBehaviour by RegisterObjectBehaviour.

2) Executing error:

In the scriptMessageCallback:

"Only object types that support object handles can use &inout. Use &in or &out instead".

I include '&in' in all references.

3) crash:

line:
r = engine->RegisterObjectBehaviour(0, asBEHAVE_ADD, "bstr f(const bstr &in, const bstr &in)", asFUNCTION(asBStrConcatenate), asCALL_CDECL);

callback:
GameEngine.exe!asCString::Compare(const char * str=0x00000000)
GameEngine.exe!operator==(const asCString & a={...}, const char * b=0x00000000)
GameEngine.exe!asCConfigGroup::FindType(const char * obj=0x00000000)
GameEngine.exe!asCScriptEngine::RegisterObjectBehaviour(const char * datatype=0x00000000, unsigned long behaviour=14, const char * decl=0x004f35b8, const asUPtr & funcPointer={...}, unsigned long callConv=0)

I think is the first param faults. I change by "bstr"

4) Executing error:

error -7 ( asNOT_SUPPORTED ):

line:
r = engine->RegisterObjectBehaviour("bstr", asBEHAVE_ADD, bstr f(const bstr &, const bstr &in)", asFUNCTION(asBStrConcatenate),asCALL_CDECL);

Change asCALL_CDECL by asCALL_GENERIC

5) Executing error:

In the scriptMessageCallback:

error: "This behaviour must be registered as global behaviour"


line:
r = engine->RegisterObjectBehaviour("bstr", asBEHAVE_ADD,bstr f(const bstr &in, const bstr &in)", asFUNCTION(asBStrConcatenate),asCALL_GENERIC);


And this is all, I don't know what's wrong. Any help? thank you!

Share this post


Link to post
Share on other sites
Quote:
Original post by WitchLord
On what platforms doesn't std::string work?


Well, I don't know but char is in everywhere :) (now you can call me silly haha)

I insert the new code, but I have some problems and doubts:

- How I can pass a bstr argument to the script? I test SetArgObject( char_address ) and don't work (the application crash), I use SetArgAddress() and dont't have problems, but don't work neither.

Script:

void OnInit( Entity@ pEntity, bstr str )
{
pEntity.Foo( str );
}

Code:

pScriptEngine->RegisterObjectMethod( "Entity", "void Foo( bstr )", asFUNCTION( Script_Foo ), asCALL_GENERIC );


- How I can get a char* form bstr?.

Script:

void OnInit( Entity@ pEntity )
{
pEntity.Foo( "niano" );
}

Code:

static void Script_Foo( asIScriptGeneric *gen )
{
const char *pszParam = what??
asBSTR niano = ( asBSTR )gen->GetArgObject( 0 ); // this don't work
asBSTR niano = ( asBSTR )gen->GetArgAddress( 0 ); // don't work
asBSTR niano = ( asBSTR )gen->GetArgPointer( 0 ); // don't work
}

Thank you.

Share this post


Link to post
Share on other sites
I don't recommend using bstr due to it being quite awkward to use. But you should be able to do it like this:

Passing bstr to script:



asBSTR bstr = asBStrAlloc(strlen(str));
strcpy(bstr, str);
*(asBSTR**)ctx->GetArgPointer() = bstr;

// The script engine will be responsible for freeing the memory after the function returns


Retrieving bstr from script:


static void Script_Foo( asIScriptGeneric *gen )
{
const char *str = **(asBSTR**)gen->GetArgPointer();

// The asIScriptGeneric interface will free the memory afterwards, so if you wish to keep the string around you need to make a copy of it.
}

Share this post


Link to post
Share on other sites
Hi, it's me again ( sorry for be so boring )

I try what you said, the part of retrieving bstr from script works fine. But when I pass a bstr to script, I found some problemas, I will try this:

Script:

void OnInit( Entity@ pEntity, bstr str01, bstr str02 )
{
pEntity.Foo( str01, str02 );
}

Code:

const char *pszString = va_arg( iter, const char* );

asBSTR bstr = asBStrAlloc( strlen( pszString) );
strcpy( ( char* )bstr, pszString );

*( asBSTR** )m_pScriptContext->GetArgPointer( iVarPos++ ) = bstr;


1) This cause a compiler error in this line:

*( asBSTR** )m_pScriptContext->GetArgPointer( iVarPos++ ) = bstr;

"cannot convert from 'asBSTR' to 'asBSTR * '". I try 2 things:

- this:

**( asBSTR** )m_pScriptContext->GetArgPointer( iVarPos++ ) = bstr;

Cause a executing error: "Unhandled exception at 0x0045c928 in GameEngine.exe: 0xC0000005: Access violation writing location 0x00000000." when execute the line.

- and this:

*(asBSTR**)m_pScriptContext->GetArgPointer( iVarPos++ ) = &bstr;

Execute properly, and call Script_Foo( asIScriptGeneric *gen ) when execute the line pEntity.Foo( str01, str02 ) in the script, but when I try to read the strings, using this:

asBSTR str01 = **( asBSTR** )gen->GetArgPointer( 0 );
asBSTR str02 = **( asBSTR** )gen->GetArgPointer( 1 );

The two strings have the same valour (the second string pass to the OnInit function), and a little after, the application crash:

"Unhandled exception at 0x7c911230 in GameEngine.exe: User breakpoint"

With this callstack:


ntdll.dll!7c970af8()
kernel32.dll!7c85e9cf()
msvcr71d.dll!_CrtIsValidHeapPointer(const void * pUserData=0x0012f4f4) Line 1807
msvcr71d.dll!_free_dbg_lk(void * pUserData=0x0012f4f4, int nBlockUse=1) Line 1132 + 0x9
msvcr71d.dll!_free_dbg(void * pUserData=0x0012f4f4, int nBlockUse=1) Line 1070 + 0xd
msvcr71d.dll!free(void * pUserData=0x0012f4f4) Line 1025 + 0xb
GameEngine.exe!asCScriptEngine::CallFree(asCObjectType * type=0x0cada788, void * obj=0x0012f4f4) Line 2672 + 0x9
GameEngine.exe!asCContext::ExecuteNext() Line 1989
GameEngine.exe!asCContext::Execute() Line 923 + 0x8
...

Thank you.



Share this post


Link to post
Share on other sites
I'm terribly sorry for taking so long about this, but I finally got the time to look into it. It turns out that it is not a bug in AngelScript, but rather that I passed the wrong instructions to you.

There are two ways of passing bstr values to a script function:

1)

// Create the object and initialize it, then give
// the pointer directly to the script engine.
// The script engine will free the object.
asBSTR *a = (asBSTR*)engine->CreateScriptObject(engine->GetTypeIdByDecl(0, "bstr"));
*a = asBStrAlloc(1);
strcpy((char*)*a, "a");
*(asBSTR**)ctx->GetArgPointer(0) = a;


2)

// Create a local instance and have the script engine copy it.
// The application must free its copy of the object.
asBSTR b = asBStrAlloc(1);
strcpy((char*)b, "b");
ctx->SetArgObject(1, &b);
asBStrFree(b);


As I mentioned before, I don't recommend using bstr due to its awkwardness.

Regards,
Andreas

Share this post


Link to post
Share on other sites

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