在为 Rebol3 编写 C 扩展时,我需要向 Rebol 传递一个指向我从 native 函数获得的对象的指针。
The documentation says有一种特殊的数据类型:“句柄:一种存储代码和数据指针的方法”。但我想要一个例子!
我想在这个句柄未绑定(bind)时调用 native 析构函数。有办法做到这一点吗?
最佳答案
要将指针存储为 Rebol 句柄,您可以这样做:
RXIARG value;
value.addr = original_pointer;
RL_SET_FIELD ( obj, RL_MAP_WORD ( (REBYTE *) "handle-attribute" ), value, RXT_HANDLE );
在此示例中,我将 obj
对象的 handle-attribute
属性设置为 original_pointer
的值
稍后您可以像这样检索句柄的值:
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" );
}
我通常使用对象来存储句柄,所以示例中的 obj
对象可以通过这种方式从 Rebol 命令框架中检索:
REBSER *obj;
obj = RXA_OBJECT ( frm, 1 );
其中 frm
是 Rebol 命令框架,1
是对象在传递给您的命令的参数列表中的位置。
如果您想使用 block 来存储句柄,则用于从 block 中存储/检索值的宏是 RL_SET_VALUE
和 RL_GET_VALUE
代替 RL_ *_FIELD
,但是您将指针复制到 value.addr
的部分不会改变。
您还可以通过使用以下指令结束命令来返回句柄作为调用扩展命令的结果:
RXA_HANDLE ( frm, 1 ) = original_pointer;
RXA_TYPE ( frm, 1 ) = RXT_HANDLE;
return RXR_VALUE;
就您的第二个问题而言,我认为目前还没有办法知道句柄何时解除绑定(bind)或被垃圾收集以触发 native 析构函数。
关于c - Rebol 3 扩展和 "handles",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23878744/