Sign in to follow this  

Struggling to understand how to use references

Recommended Posts

I'm struggling to understand how to use the ref add-on both in script and across the script/c++ interface.

 

I understand the basics of pointers but am having a hard time wrapping my head around how angelscript interfaces with c++ for function calls.

 

Problem one: error when using refs with string.

 

script code

string str1;
string str2;
ref @strref1;
	
str1 = "hello world";
	
@strref1 = str1;
	
print(str1);
	
str6 = cast<string>(strref1);

When compiling the script, this returns: ERR  : Illegal target type for reference cast.

Why can't a ref be case to to a string?

 

 

Problem two: problems passing refs to c++

 

declared a function:

//C++
void test_pass_ref(CScriptHandle *&arg){
	void *ptr;
	
	ptr = arg->GetRef();
	cout << "ptr is " << ptr << endl;
	cout<< "str passed is " << static_cast <char*> (ptr) << endl;
	cout<< "exit"<<endl;
}

//registered like this
r = engine->RegisterGlobalFunction("void test_pass_ref(ref@ &in)", asFUNCTION(test_pass_ref), asCALL_CDECL);

Attempting to use it like this in a script

string str5;
ref @strref1;

str5 = "hello world";
@strref1 = str5;
test_pass_ref(strref1);

Get the following output:

ptr is 0
str passed is Segmentation fault

 

Why does GetRef() not return the pointer of the string? Any help in understanding would be appreciated.

Share this post


Link to post
Share on other sites

As stated by its documentation, the ref type "can refer to any object type (as long as it is a reference type)". However, the string type is registered as a value type. The distinction between a value type and a reference type is somewhat important in all of AngelScript, as value types don't support handles (@) or inout references (&), which, deeper down, is because they don't register garbage collection/reference counting mechanisms, thus making it unsafe to store any references to them other than the object itself. With some effort, it's possible to register string as a reference type, although consider whether the purposes you need it for are worth it.

 

The second problem you're experiencing is, first off, because the ref type can't hold references to strings, as explained earlier. If it were to occur for other types, make sure you're using an AngelScript version that incorporates revision 2347, such as the latest stable release (2.31.2). If updating the library version your project uses is not viable, or just if you'd rather have reasonable code, change the AngelScript function signature to "void test_pass_ref(ref@)" and the C++ one to "void test_pass_ref(CScriptHandle *arg)". There is no reason to ever use "@ &in" in AngelScript. And regardless of all that, if assigning it to the reference and passing it to the function actually worked, I guarantee that casting what's internally an std::string* to char* and printing that, wouldn't do anybody any good.

Edited by Sir Ementaler

Share this post


Link to post
Share on other sites

Thanks for your response and help. Another read-through of the documentation would probably do me some good.

 

I'll re-do this test with a different class and see if I still have issues.

Share this post


Link to post
Share on other sites

For those curious, i was able to get this to work with handles, refs, and a custom class "Person":

C++ function declarations:

void GetPersonObject(Person &p1);
void GetPersonHandle(Person *&ptr);
void GetRefToPerson(CScriptHandle *h1);

registered as:

RegisterGlobalFunction("void GetPersonObject(Person &)", asFUNCTION(GetPersonObject), asCALL_CDECL);
RegisterGlobalFunction("void GetPersonHandle(Person@ &out)", asFUNCTION(GetPersonHandle), asCALL_CDECL);
RegisterGlobalFunction("void GetRefToPerson(ref@)", asFUNCTION(GetRefToPerson), asCALL_CDECL);

Used in script as follows:

Person a;    
GetPersonObject(a);    
Person@ b;    
GetPersonHandle(@b);
ref @r1;
@r1 = a;
GetRefToPerson(r1);

where

void GetRefToPerson(CScriptHandle *h1)
{
    int type_id;
    Person *pp1;
    void *ptr = operator new(8);
    
    type_id = h1->GetTypeId();
    h1->Cast(&ptr,type_id);
    
    if(ptr != NULL)
    {
        //determined it's of type person
        pp1 = static_cast<Person*>(h1->GetRef());        
        cout<<"name of person is: "<<p1->name<<endl;
    }
}

Thanks again, Sir Ementaler

Share this post


Link to post
Share on other sites

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