Advertisement

scriptstring.h -- necessary?

Started by August 01, 2007 09:08 PM
8 comments, last by WitchLord 16 years, 8 months ago
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.
Omit if you don't want to pass strings as function parameters between AS and you're code.
Advertisement
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.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

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 ∈ or &out instead".

I include '∈' in all references.

3) crash:

line:
r = engine->RegisterObjectBehaviour(0, asBEHAVE_ADD, "bstr f(const bstr ∈, const bstr ∈)", 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 ∈)", 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 ∈, const bstr ∈)", asFUNCTION(asBStrConcatenate),asCALL_GENERIC);


And this is all, I don't know what's wrong. Any help? thank you!
On what platforms doesn't std::string work?

There is a bstr implementation in the test_feature/source directory.

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

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.
Advertisement
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.}

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

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.



Hmm, I'll have to make some tests. Maybe this is a bug in AngelScript.




AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

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

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