To store a pointer as a Rebol handle you can do something like this:
RXIARG value;
value.addr = original_pointer;
RL_SET_FIELD ( obj, RL_MAP_WORD ( (REBYTE *) "handle-attribute" ), value, RXT_HANDLE );
In this example I'm setting the handle-attribute
attribute of the obj
object to the value of original_pointer
Later you can retrieve the value of the handle like this:
int dtype = 0;
RXIARG value;
dtype = RL_GET_FIELD ( obj, RL_MAP_WORD ( (REBYTE *) "handle-attribute" ), &value );
switch ( dtype ) {
case RXT_NONE:
printf ( "Invalid handle: none\n" );
break;
case RXT_HANDLE:
original_pointer = value.addr;
break;
default:
printf ( "Invalid handle: none\n" );
}
I usually use objects to store handles into, so the obj
object in the example can be retrieved from Rebol command frame this way:
REBSER *obj;
obj = RXA_OBJECT ( frm, 1 );
where frm
is Rebol command frame and 1
is the position of the object in the parameter list passed to your command.
If you want to use blocks to store handles the macros to use to store/retrieve a value from a block are RL_SET_VALUE
and RL_GET_VALUE
in place of RL_*_FIELD
, but the part where you copy your pointer to value.addr
doesn't change.
You can also return a handle as a result of calling an extension's command by ending the command with the following instructions:
RXA_HANDLE ( frm, 1 ) = original_pointer;
RXA_TYPE ( frm, 1 ) = RXT_HANDLE;
return RXR_VALUE;
As far as your second question is concerned I think that by now there's no way to know when the handle is unbound or gets garbage collected to trigger a native destructor.