- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Lua教程(二十二):userdata由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
在Lua中可以通过自定义类型的方式与C语言代码更高效、更灵活的交互。这里我们通过一个简单完整的示例来学习一下Lua中userdata的使用方式。需要说明的是,该示例完全来自于Programming in Lua。其功能是用C程序实现一个Lua的布尔数组,以提供程序的执行效率。见下面的代码和关键性注释。 。
。
#include <lua.hpp> #include <lauxlib.h> #include <lualib.h> #include <limits.h> 。
。
#define BITS_PER_WORD (CHAR_BIT * sizeof(int)) #define I_WORD(i) ((unsigned int)(i))/BITS_PER_WORD #define I_BIT(i) (1 << ((unsigned int)(i)%BITS_PER_WORD)) 。
typedef struct NumArray { int size; unsigned int values[1]; } NumArray,
extern "C" int newArray(lua_State* L) { //1. 检查第一个参数是否为整型。以及该参数的值是否大于等于1. int n = luaL_checkint(L,1); luaL_argcheck(L, n >= 1, 1, "invalid size."); size_t nbytes = sizeof(NumArray) + I_WORD(n - 1) * sizeof(int); //2. 参数表示Lua为userdata分配的字节数。同时将分配后的userdata对象压入栈中。 NumArray* a = (NumArray*)lua_newuserdata(L,nbytes); a->size = n; for (int i = 0; i < I_WORD(n - 1); ++i) a->values[i] = 0; //获取注册表变量myarray,该key的值为metatable。 luaL_getmetatable(L,"myarray"); //将userdata的元表设置为和myarray关联的table。同时将栈顶元素弹出。 lua_setmetatable(L,-2); return 1; } 。
extern "C" int setArray(lua_State* L) { //1. Lua传给该函数的第一个参数必须是userdata,该对象的元表也必须是注册表中和myarray关联的table。 //否则该函数报错并终止程序。 NumArray* a = (NumArray*)luaL_checkudata(L,1,"myarray"); int index = luaL_checkint(L,2) - 1; //2. 由于任何类型的数据都可以成为布尔值,因此这里使用any只是为了确保有3个参数。 luaL_checkany(L,3); luaL_argcheck(L,a != NULL,1,"'array' expected."); luaL_argcheck(L,0 <= index && index < a->size,2,"index out of range."); if (lua_toboolean(L,3)) a->values[I_WORD(index)] |= I_BIT(index); else a->values[I_WORD(index)] &= ~I_BIT(index); return 0; } 。
extern "C" int getArray(lua_State* L) { NumArray* a = (NumArray*)luaL_checkudata(L,1,"myarray"); int index = luaL_checkint(L,2) - 1; luaL_argcheck(L, a != NULL, 1, "'array' expected."); luaL_argcheck(L, 0 <= index && index < a->size,2,"index out of range"); lua_pushboolean(L,a->values[I_WORD(index)] & I_BIT(index)); return 1; } 。
extern "C" int getSize(lua_State* L) { NumArray* a = (NumArray*)luaL_checkudata(L,1,"myarray"); luaL_argcheck(L,a != NULL,1,"'array' expected."); lua_pushinteger(L,a->size); return 1; } 。
extern "C" int array2string(lua_State* L) { NumArray* a = (NumArray*)luaL_checkudata(L,1,"myarray"); lua_pushfstring(L,"array(%d)",a->size); return 1; } 。
static luaL_Reg arraylib_f [] = { {"new", newArray}, {NULL, NULL} },
static luaL_Reg arraylib_m [] = { {"set", setArray}, {"get", getArray}, {"size", getSize}, {"__tostring", array2string}, //print(a)时Lua会调用该元方法。 {NULL, NULL} },
extern "C" __declspec(dllexport) int luaopen_testuserdata(lua_State* L) { //1. 创建元表,并将该元表指定给newArray函数新创建的userdata。在Lua中userdata也是以table的身份表现的。 //这样在调用对象函数时,可以通过验证其metatable的名称来确定参数userdata是否合法。 luaL_newmetatable(L,"myarray"); lua_pushvalue(L,-1); //2. 为了实现面对对象的调用方式,需要将元表的__index字段指向自身,同时再将arraylib_m数组中的函数注册到 //元表中,之后基于这些注册函数的调用就可以以面向对象的形式调用了。 //lua_setfield在执行后会将栈顶的table弹出。 lua_setfield(L,-2,"__index"); //将这些成员函数注册给元表,以保证Lua在寻找方法时可以定位。NULL参数表示将用栈顶的table代替第二个参数。 luaL_register(L,NULL,arraylib_m); //这里只注册的工厂方法。 luaL_register(L,"testuserdata",arraylib_f); return 1; } 。
轻量级userdata:
。
之前介绍的是full userdata,Lua还提供了另一种轻量级userdata(light userdata)。事实上,轻量级userdata仅仅表示的是C指针的值,即(void*)。由于它只是一个值,所以不用创建。如果需要将一个轻量级userdata放入栈中,调用lua_pushlightuserdata即可。full userdata和light userdata之间最大的区别来自于相等性判断,对于一个full userdata,它只是与自身相等,而light userdata则表示为一个C指针,因此,它与所有表示同一指针的light userdata相等。再有就是light userdata不会受到垃圾收集器的管理,使用时就像一个普通的整型数字一样.
最后此篇关于Lua教程(二十二):userdata的文章就讲到这里了,如果你想了解更多关于Lua教程(二十二):userdata的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我对 react 和尝试从 .json 文件(称为 userData.json)获取数据还很陌生,但是即使 userData 是一个数组,.map 也不起作用。 我已经检查过了 console.lo
在我的 asp.net 网站上。我将一些数据放入表单例份验证票证的 UserData 部分。稍后我可以使用访问这些数据 (FormsIdentity)(HttpContext.Current.User
OSX 中的磁盘实用程序可以轻松地将 SD 卡镜像装载为设备,但其他 img 文件则不然。 我想将我刚刚在 Android 模拟器中创建的数据库从驱动器中取出并放入我的 osx 文件系统中。 我使用
这是一个小的 C 测试程序来演示我所看到的。它向 Lua 注册一个新的对象类型并执行一个 Lua 脚本。当脚本调用 __len 元方法时,我希望堆栈上只传递一个参数——对象 userdata。相反,它
在Lua中可以通过自定义类型的方式与C语言代码更高效、更灵活的交互。这里我们通过一个简单完整的示例来学习一下Lua中userdata的使用方式。需要说明的是,该示例完全来自于Programming
我需要搜索事件日志,这是我的代码: IEnumerable q = ( from entry in el.Entries.Cast() where entry.Source =
在 C 函数声明中,我看到了这个参数定义: void *userData 所以,那到底是什么?我的猜测:void 表示它可以是任意的,甚至什么都不是。几乎类似于 objective-c 的 id。它只
我在 lua 中有一个接受用户数据对象的函数。 function Class:AttachToUserdataObject(userdataObject) userDataObject.table
我在 lua 中有一个接受用户数据对象的函数。 function Class:AttachToUserdataObject(userdataObject) userDataObject.table
我有以下代码: if (HttpContext.Current.Request.IsAuthenticated == false) { // this isn't reached so i k
我需要我的标记来保存一些数据(不仅仅是位置、片段和标题,它们已经在使用中)。我创建了一个字典,然后将 marker.userData 设置为该字典。但是,我在从字典中获取值时遇到问题。任何帮助将不胜感
只是想在这里确认一下。是否可以直接将 jqGrid 的 userData 与 JavaScript 类型一起使用(而不是使用带有字段的对象)? 如果我修改example在 jqGrid 文档中,我想将
如何适本地缓存从用户的 callbackBegin() 生成的 userData并发送给用户的callbackEnd() . 简单版本(无用户数据 - demo) 我想创建一个支持回调的复杂数据库。对
我正在根据本教程使用表单例份验证为 ASP.Net 4.0 站点实现自定义标识类: Forms Authentication Configuration and Advanced Topics 我想在
我相信你们中的一些人可能会遇到这个问题。我有一个用 C++ 编写的名为矩阵的用户数据对象,使用常用的运算符重载方式,例如。 CMatrix& operator=(const CMatrix& b);
为了防止 Cluster Auto Scaler 终止某些节点,我需要使用以下内容注释它们: cluster-autoscaler.kubernetes.io/scale-down-disabled=
我想使用 LuaJIT,因为它能够在 Lua 中创建结构和数组。但是我使用数据的函数需要存储数据的用户数据或字符串(不是字符串表示形式,仅用作容器)。 但是通过api我看不到这是否可能。是吗? 谢谢。
UserData: Fn::Base64: !Sub | #!/bin/bash echo "Start" >> /v
我有一个运行良好的 Cloudformation 模板。当我以 Base64 形式为其中一项启动配置添加用户数据时,CloudFormation Ruby API 回复我的 JSON 格式不正确。这是
我正在构建并尝试部署打包的 Electron 应用程序。对于我使用的 package Electron package 器 Electron 安装程序-debian Electron 安装程序-dmg
我是一名优秀的程序员,十分优秀!