LUA Registry

探讨了在C函数中如何使用Lua CAPI中的registry和upvalues来存储非局部数据,详细介绍了这两种方法的应用场景及操作流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



Storing State in C Functions

C functions need to keep some non-local data, that is, data that
outlive their invocation.

The C API also offers two basic places to store non-local
data: the registry and upvalues.

The registry is a global table that can be accessed only by C code.3 Typically,you use it to store data to be shared among several modules.

If you need to store data private to a module or to a single function, you should use upvalues.

在为LUA语言拓展功能时,需要在C function中保存状态。在LUA  C API 中提供两种基本的方法来存储非局部数据。the register and upvalues.


1、the registry 是一个全局Table.可以使用registry在多个C module中保存状态。


2、the upvalues可以保存一个module的私有数据。

The registry


The registry is always located at a pseudo-index, whose value is defined by LUA_REGISTRYINDEX. A pseudo-index is like an index into the stack, except that

its associated value is not in the stack.

Most functions in the Lua API that accept indices as arguments also accept pseudo-indices — the exceptions being those
functions that manipulate the stack itself, such as lua_remove and lua_insert.

the registry 位于伪索引上。一个伪索引像在虚拟栈上面的索引但是伪索引的值不在虚拟栈上面。


The registry is a regular Lua table. As such, you can index it with any Lua value but nil. 

the registry是一个伪索引为LUA_REGISTRYINDEX ,值不在虚拟栈上面的普通table数据结构。可以通过任何值来索引在registry里面的值。


However, because all C modules share the same registry, you must choose with care what values you use as keys, to avoid collisions.

所有的C module可以共享共同的registry,可以使用不同的键来避免冲突。



For instance, to get a value stored with key “Key” in the registry, you can use the following call:
lua_getfield(L, LUA_REGISTRYINDEX, "Key");


String keys are particularly useful when you want to allow other independent libraries to access your data, because all they need to know is the key name.


The reference system


You should never use numbers as keys in the registry, because such keys are reserved for the reference system.

在伪索引为LUA_REGISTRYINDEX获取到registry Table时,不能使用 索引来存储 多个C module的数据。因为索引被引用系统使用。


Function luaL_ref creates new references: int r = luaL_ref(L, LUA_REGISTRYINDEX);

The previous call pops a value from the stack, stores it into the registry with a fresh integer key, and returns this key. We call this key a reference.

luaL_ref(L,LUA_REGISTRYINDEX) 从Register Table 弹出一个没有被使用的索引值.


we use references mainly when we need to store a reference to a Lua value inside a C structure.

As we have seen, we should never store pointers to Lua strings outside the C function that retrieved them.

Moreover, Lua does not even offer pointers to other objects, such as tables or functions.

So, we cannot refer to Lua objects through pointers.

Instead, when we need such pointers, we create a reference and store it in C.

在C API 中,我们不应该C Function存储指向LUA Strings的指针。

同时,在LUA语言中也不应该提供指向其他对象,Table和Function的指针。


当如果我们需要指针时,我们可以在通过C API  luaL_ref()创建一个应用并且存储在C语言中。



To push the value associated with a reference r onto the stack, we simply write this:
lua_rawgeti(L, LUA_REGISTRYINDEX, r);


当使用luaL_ref()创建一个引用时,我们PUSH 引用到虚拟栈上面。


Finally, to release both the value and the reference, we call luaL_unref:
luaL_unref(L, LUA_REGISTRYINDEX, r);


After this call, a new call to luaL_ref may return again this reference.
当我们调用 luaL_unref()时,我们释放引用返回到registry table。


The reference system treats nil as a special case. Whenever we call luaL_ref for a nil value, it does not create a new reference, but instead returns the
constant reference LUA_REFNIL. The next call has no effect:
luaL_unref(L, LUA_REGISTRYINDEX, LUA_REFNIL);





 The reference system treats nil as a special case. Whenever we call luaL_ref for a nil value, it does not create a new reference, but instead returns the
constant reference LUA_REFNIL.

The next call has no effect: luaL_unref(L, LUA_REGISTRYINDEX, LUA_REFNIL);















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值