Jump to content

  • Log In with Google      Sign In   
  • Create Account

FREE SOFTWARE GIVEAWAY

We have 4 x Pro Licences (valued at $59 each) for 2d modular animation software Spriter to give away in this Thursday's GDNet Direct email newsletter.


Read more in this forum topic or make sure you're signed up (from the right-hand sidebar on the homepage) and read Thursday's newsletter to get in the running!


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