Jump to content

  • Log In with Google      Sign In   
  • Create Account


Magnitude

Member Since 24 Jun 2013
Offline Last Active Jun 25 2013 08:20 PM
-----

Topics I've Started

Problem: Attempting to pass around a void* as a handle within Angelscript.

24 June 2013 - 04:27 PM

The Problem

I've attempted to register an object method ( asEngine_RegisterObjectMethod ) that takes in a GlobalData* and a uint, than returns a ref type.  Something about returning the ref however seems to cause the function to pass in an invalid pointer as the first parameter.  Modifying the function to return a non-generic type seems to correct the problem.

 

What I am trying to do -- Bigger Picture

I want to retrieve some data in the form of a void* and easily pass it around to various other bound functions.

In this simple example I want to retrieve a void* from an object as a generic handle, cast that handle, than pass that handle to another C-style function.

 

I want to able to return a void* as a ref ( or ref@, not sure since ref seems to be a special case), then cast that to a Entity@ and pass it along to a registered function that can take an Entity*.

 

I'd also like to avoid needing the user to register a cast function if they don't need to.  It seems like CScriptHandle can already be casted from one handle type to another.

 

This is ideally how I want the angelscript to look when the user attempts to get/pass around the data.

GLOBALDATA@ GlobalData = GetGlobalData();
ENTITY@ Entity = cast<ENTITY>(GlobalData.GetData( 2 ));
if( Entity !is null ){
    Entity_ProcessEntity( Entity );
}

I have registered the CScriptHandle type with the asEngine, however I seem to be missing something important during the implementation as things are not working as expected.

 

This is what the simplified C++ modules look like.

static class GlobalData
{
public:
   void* GetData( uint index ){ return _data[index]; }

private:
   void** _data[10];
} GlobalDataInstance;


//C-Style interface for GlobalData
GlobalData* GlobalData_GetGlobalData( void ){
    return &GlobalDataInstance;
}

void* GlobalData_GetData( GlobalData* globalData, uint index ){
   return globalData->GetData(index);
}

void Entity_ProcessEntity( Entity* entity ){
    entity->DoWork();
}

This is how they are registered with asEngine

Result = asEngine_RegisterGlobalFunction( Engine, "GLOBALDATA@ GetGlobalData()", asFUNCTION_t( &GlobalData_GetGlobalData), asCALL_CDECL );
Result = asEngine_RegisterObjectType( Engine, "GLOBALDATA", 0, asOBJ_REF | asOBJ_NOCOUNT );
Result = asEngine_RegisterObjectMethod( Engine, "GLOBALDATA",   "ref GetData( uint Index) const",  asFUNCTION_t(&GlobalData_GetData), asCALL_CDECL_OBJFIRST );

Result = asEngine_RegisterGlobalFunction( Engine, "void Entity_ProcessEntity( ENTITY@ entity)", asFUNCTION_t( &Entity_ProcessEntity), asCALL_CDECL );

asEngine_RegisterObjectMethod( Engine, "GLOBALDATA",   "ref GetData( uint Index) const",  asFUNCTION_t(&GlobalData_GetData), asCALL_CDECL_OBJFIRST );
This seems to be where the problem is occuring.  The GlobalData* provided here is not valid.  It is not null, however it is not GlobalDataInstance.

 

It could be that CScriptHandle is not the right solution for what i want to do, which is why I've included all of the additional information.

 

 


PARTNERS