[英]Using C variable inside Lua alongside nested functions
这是对我先前关于嵌套注册的C函数的先前问题的一种补充:在此处找到: 使用嵌套表在Lua中调用函数
上一个问题为我提供了添加如下嵌套函数的答案:
dog.beagle.fetch()
我也想在该级别使用变量,例如:
dog.beagle.name
dog.beagle.microchipID
我希望此字符串和数字在C中分配并且可由Lua访问。 因此,在C代码中,变量可以定义为:
int microchipIDNumber;
char dogname[500];
C变量需要通过Lua中的赋值进行更新,并且当其位于等号右侧时,其值需要由Lua检索。 我尝试了__index和__newindex元方法概念,但是当我在变量的Lua路径中有2个点时,我尝试的一切似乎都崩溃了。 我知道我可能会使这两个点变得更加复杂,但这使组织更容易在Lua代码中阅读。 我还需要获取分配事件,因为当microchipIDNumber值更改时,我需要启动一些硬件。 我假设我可以在设置值时通过__newindex进行此操作。
关于如何编写元表和方法以完成嵌套的任何想法? 可能是因为我以前的函数声明使Lua感到困惑吗?
冒号运算符( :
)在Lua仅用于功能。 考虑以下示例:
meta = {}
meta["__index"] = function(n,m) print(n) print(m) return m end
object = {}
setmetatable(object,meta)
print(object.foo)
index函数将只打印它传递的两个参数,然后返回第二个参数(我们也将打印该参数,因为仅执行object.foo
是语法错误)。 输出将是table: 0x153e6d0 foo foo
和新行。 因此, __index
获得了我们要在其中查找变量的对象及其名称。 现在,如果我们用object:foo
替换object.foo
,我们将得到:
input:5: function arguments expected near ')'
这是因为:
in :
object:foo
是object.foo(object)
语法糖,因此Lua希望您将为函数调用提供参数。 如果我们确实提供了参数( object:foo("bar")
),则会得到以下结果:
table: 0x222b3b0
foo
input:5: attempt to call method 'foo' (a string value)
因此我们的__index
函数仍然被调用,但是没有传递参数-Lua只是尝试调用返回值。 因此,请勿对成员使用:
。
顺便说一句,让我们看一下如何在Lua和C之间同步变量。这实际上是相当复杂的,并且有不同的方法来实现。 一种解决方案是结合使用__index
和__newindex
。 如果您在C语言中拥有beagle
结构,则建议您使用这些C函数并将它们作为C闭包推入Lua表的元表中,并以指向C结构的指针作为上值。 看看这对一些信息lua_pushcclosure
和这个总体上关闭在Lua。
如果您没有可以引用的单一结构,则它将变得更加复杂,因为您必须以某种方式在C端存储对variableName-variableLocation
,并知道每种类型是什么。 您可以在实际的Lua表中维护这样的列表,因此dog.beagle
将是变量名到一两个变量的映射。 对于这种“东西”有几种选择。 首先-一个简单的用户数据(即-C指针),但是接下来您将要弄清楚指向的内容,这样您就知道要为__index
推送的Lua类型以及为__newindex
弹出的内容。 另一个选择是推两个功能/关闭。 您可以为必须处理的每种类型(数字,字符串,表格等)创建一个C函数,并为每个变量推送适当的函数,或者使一个带有参数的uber-closure给出所要赋予的类型,然后只是改变您推销的价值。 在这种情况下, __index
和__newindex
函数将简单地为给定的变量名查找适当的函数并调用它,因此在Lua中实现它可能是最容易的。
对于两个函数,您的dog.beagle
可能看起来像这样( 不是实际的Lua语法 ):
dog.beagle = {
__metatable = {
__index = function(table,key)
local getFunc = rawget(table,key).get
return getFunc(table,key)
end
__newindex = function(table,key,value)
local setFunc = rawget(table,key).set
setFunc(table,key,value)
end
}
"color" = {
"set" = *C function for setting color or closure with an upvalue to tell it's given a color*,
"get" = *C function for getting color or closure with an upvalue to tell it to return a color*
}
}
关于上述内容的注意事项:1. __metatable
直接设置对象的__metatable
字段-它用于隐藏真正的元表。 使用setmetatable(object,metaable)。 2.注意rawget
的用法。 我们需要它,因为否则尝试从__index
内获取对象的字段将是无限递归。 3.如果rawget(table,key)
返回nil
,或者返回的内容没有get
/ set
成员,则必须进行一些错误检查。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.