这一段时间看了《programming in lua》中的第28章,看一遍并不是很难,但是只是朦胧的感觉,雾里看花,水中望月。最终还是决定敲出来自己看看,练练手,结果受益不少,也遇到了一些问题,记在这里。自己做一个总结,也希望能帮助和我一样lua的初学者。

1. 书上并没有写清楚对于CAPI的制作和使用内容。主要包括dll的生成,以及使用

(1)dll生成。

  直接用vs新建一个dll工程,要记得包含依赖路径。如下图所示,包含你的lua安装路径。

  工程名要和库的最终名字一致(默认是一致的)。luaopen_array(lua_State *L)也最好一致。这一块,我没有去研究和测试,就是按照书上来做的,没有碰到什么大的问题,主要和使用方式有一些关系。

(2)使用

两种方法:

第一种:require "myarray"。这就需要dll的名字是myarray.dll。而且luaopen_xxx(lua_State *L)也是luaopen_array的形式;

第二种:package.loadlib("array", "luaopen_array")()。这种的话,第一个参数array是你在写c代码时候注册的table名字,后面一个函数名。这种使用方式我个人觉得是需要dll名字以及注册的table名必须是"array",但是luaoepn_xxx就不需要了。

(3)linux

  直接使用命令:gcc mylib.c -fPIC -shared -o libmylib.so即可生成可以使用的动态库。

  使用和window下面的使用一样,自己用的是第二种方法:package.loadlib("./libmydir.so", "luaopen_mydir")()

2. 一些问题

(1)直接使用loadlib不行

  mylib = loadlib("mylib", "luaopen_mylib")

解决:加上库,package.loadlib

(2)使用package.loadlib的时候报错

描述:lua: capi_study.lua:57: attempt to call a nil value

原因:工程名字生成的库名字和使用的时候不一致出错

(3)luaL_openlib和luaL_register

  *接口变化,我用的lua版本是5.1.所以用luaL_register接口,而不是书上仍然使用的luaL_openlib接口。官网的document的5.1《reference manual》中有提到,可以自己去看。

  *linux却仍然还是需要使用前者。(linux下面的版本是5.2.0了,不明白是什么原因)

(4)面向对象例子报错

描述:lua: capi_study.lua:102: calling 'size' on bad self (luaBook.array expected, got userdata)

原因:void *ud = luaL_checkudata(L, 1, "LuaBook.array");中的"LuaBook.array"写成了"luaBook.array"

结果:Success!

package.loadlib("array", "luaopen_array")()
a = array.new()
print(a:size())
a:set(, 3.4)
print(a:get())

输出结果:

3.4

(5)linux编译报错

描述:“错误:数组元素的类型不完全”

原因:

*用gcc4编译时出现数组元素的类型不完全错误,这是因为gcc4不允许类型在声明前使用。【引用:http://blog.csdn.net/horsefaced/article/details/1678965】

*luaL_Reg写成了luaL_reg

解决:

(6)linux编译警告

描述:警告:传递参数 2 (属于 ‘lua_getmetatable’)时将指针赋给整数,未作类型转换

原因:低级错误luaL_getmetatable写成了lua_getmetatable,希望碰到这个问题的能够不用再纠结了

3.一个例子

  附上dir例子的源码,linux编译通过。

#include <math.h>
#include <dirent.h>
#include <errno.h>
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h" /* forward declaration */
static int dir_iter(lua_State *L); static int l_dir(lua_State *L){
const char *path = luaL_checkstring(L, ); /* create a userdatum */
DIR **d = (DIR **)lua_newuserdata(L, sizeof(DIR *)); /* set its metatable */
luaL_getmetatable(L, "LuaBook.dir");
lua_setmetatable(L, -); /* try to pen then given dirctory */
*d = opendir(path);
if (*d == NULL)
luaL_error(L, "cannot open %s: %s", path, strerror(errno)); /* creates and returns the iterator function */
lua_pushcclosure(L, dir_iter, );
return ;
} static int dir_iter(lua_State *L){
DIR *d = *(DIR **)lua_touserdata(L, lua_upvalueindex());
struct dirent *entry;
if (( entry = readdir(d)) != NULL){
lua_pushstring(L, entry->d_name);
return ;
}
else return ; /* no more valuse to return */
} static int dir_gc(lua_State *L){
DIR *d = *(DIR **)lua_touserdata(L, );
if (d) closedir(d);
return ;
} int luaopen_mydir (lua_State *L){
luaL_newmetatable(L, "LuaBook.dir"); /* set its __Gc field */
lua_pushstring(L, "__gc");
lua_pushcfunction(L, dir_gc);
lua_settable(L, -); /* register the 'dir' function */
lua_pushcfunction(L, l_dir);
lua_setglobal(L, "dir"); return ;
}

使用和结果

> package.loadlib("./libmydir.so", "luaopen_mydir")()
> for fname in dir(".") do print(fname) end
.
..
libmylib.so
libdir.so
dir.c
.dir.c.swp
dir.so
mydir_none.c
mylib.c
libmydir.so
mydir.c
capi_study.lua
lua-5.1.
>

4. 总结

(1)lua调用c函数,返回的就是栈上的内容。例如:你在c函数压入一个整数,那么返回的第一个就是这个整数。

(2)linux命令:gcc mylib.c -fPIC -shared -o libmylib.so

(3)看书学习的时候,当觉得朦胧不清晰的时候,要放慢速度,最好的就是Do it。敲出来去看看,会有不同的收获,感觉有东西,这种感觉个人觉得是学习的时候最好的。

lua学习笔记之userdata的更多相关文章

  1. Lua 学习笔记(一)

    Lua学习笔记 1.lua的优势 a.可扩张性     b.简单     c.高效率     d.和平台无关 2.注释 a.单行注释 --        b.多行注释 --[[  --]] 3.类型和 ...

  2. [转]LUA 学习笔记

    Lua 学习笔记 入门级 一.环境配置 方式一: 1.资源下载http://www.lua.org/download.html 2.用src中的源码创建了一个工程,注释调luac.c中main函数,生 ...

  3. Lua学习笔记6:C++和Lua的相互调用

        曾经一直用C++写代码.话说近期刚换工作.项目组中的是cocos2dx-lua,各种被虐的非常慘啊有木有.     新建cocos2dx-lua项目.打开class能够发现,事实上就是C++项 ...

  4. Lua学习笔记4. coroutine协同程序和文件I/O、错误处理

    Lua学习笔记4. coroutine协同程序和文件I/O.错误处理 coroutine Lua 的协同程序coroutine和线程比较类似,有独立的堆栈.局部变量.独立的指针指令,同时又能共享全局变 ...

  5. (转)Lua学习笔记1:Windows7下使用VS2015搭建Lua开发环境

    Lua学习笔记1:Windows7下使用VS2015搭建Lua开发环境(一)注意:工程必须添加两个宏:“配置属性”/“C或C++”/“预处理器”/“预处理器定义”,添加两个宏:_CRT_SECURE_ ...

  6. Lua学习笔记:面向对象

    Lua学习笔记:面向对象 https://blog.csdn.net/liutianshx2012/article/details/41921077 Lua 中只存在表(Table)这么唯一一种数据结 ...

  7. Lua学习笔记(二):基本语法

    Lua学习指南:http://www.lua.org/manual/ 首先我们要明确的一点是:在Lua中,除了关键字外一切都是变量. Lua关键字 可以查看这个地址:http://www.lua.or ...

  8. Lua学习笔记一

    学习了有一周多了.之前一直不想献丑,但还是记录下这个过程. 第1章  开发软件搭建 1. ubuntu 下lua安装 sudo apt-get install lua5.1 2.win下的环境搭建. ...

  9. lua学习笔记

    工作需要,上周对lua赶进度似地学习了一遍,主要参考<lua中文教程>一书,中间参考一些<lua游戏开发实践>,首先说说这两本书,后者不适合初学,里面是对一个游戏脚本系统进行粗 ...

随机推荐

  1. MySQL修改提示符

    MySQL提示符 \D 完整日期 \d 当前数据库 \h 服务器名称 \u 当前用户 1.连接之前修改提示符 mysql -uroot -proot --prompt [MySQL提示符] 2.连接之 ...

  2. 解析ES6 Promise

    ES6 Promise 概念之类的,大概读者都应该有所知道,接下来我们直入终点. 先让我们来看看什么是Promise吧,他是一个object,类,arry,function? 首先,学习它的时候应该讲 ...

  3. 兼容IE6-9,FF,Chrome的box-shadow效果(纯CSS)

    昨天由于工作关系,遇上了这个问题,苦恼一日无解——残念. 所幸终于在今天早上得到了解决,遗憾的是灵活性不够强,不能根据内容自适应,要配合JS才能达到自适应效果 不过总结到这里已经很满意了,毕竟规律已经 ...

  4. idea 下 启动maven项目,mybatis报错 Error parsing SQL Mapper Configuration. Cause: java.io.IOException。。。。。

    我的具体报错日志是   Error parsing SQL Mapper Configuration. Cause: java.io.IOException  Could not find resou ...

  5. freemarker实现通用布局的模板拆分与复用

    原文:http://www.hawu.me/coding/733 一.基础页面布局 假设我们项目页面的通用布局如下图所示: 实现这样的布局的基本html代码如下:           XHTML   ...

  6. 初学spring-boot

    部分转载自:http://blog.java1234.com 一.简介 Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架 ...

  7. 常用Oracle的SQL语句20181206更新

    --clob转字符串:dbms_lob.substr() --锁表:select object_name,machine,s.sid,s.serial# from v$locked_object l, ...

  8. bzoj 3064: Tyvj 1518 CPU监控

    Description 1.区间加 \(z\) 2.区间覆盖为 \(z\) 3.查询区间最大值 4.查询区间历史最大值 Solution 线段树维护历史最值,思想大致是维护标记出现过的最大值 考虑这种 ...

  9. MVVM - 事件转命令2

    在使用MVVM模式时, 按照模式的规则是尽量不直接使用事件. 所以对于以前一直使用事件模式的同行来说确实有点头疼. 还好微软给我们提供了几种间接使用事件(命令)的方法, 下面我就来看看这几种方法: I ...

  10. Rabbit主题交换机

    主题交换机类型为:topic. 是直连交换机的一种.只是比直连交换机更灵活,在路由键上引入了通配符的概念 topic交换机支持通配符的路由键. *表示匹配一个词. #匹配所有 生产者 : packag ...