lua52 C API测试代码
- //这是一篇lua与C++交互的情景测试
- #include <lua.hpp>
- #include <lauxlib.h>
- #include <lualib.h>
- #include <string.h>
- #include <limits.h>
- #pragma region not_importent_
- static void stackDump (lua_State *L)
- {
- int i;
- int top = lua_gettop(L);
- for(i=1;i<=top;i++){
- /*repeatforeachlevel*/
- int t = lua_type(L, i);
- switch (t) {
- case LUA_TSTRING:
- /* strings */
- printf("`%s'", lua_tostring(L, i));
- break;
- case LUA_TBOOLEAN:
- /* booleans */
- printf(lua_toboolean(L, i) ? "true" : "false");
- break;
- case LUA_TNUMBER:
- /* numbers */
- printf("%g", lua_tonumber(L, i));
- break;
- default:
- /* other values */
- printf("%s", lua_typename(L, t));
- break;
- }
- printf(" ");
- /* put a separator */
- }
- printf("\n");
- /* end the listing */
- }
- void error (lua_State *L, const char *fmt, const char *str) {
- printf(fmt, str);
- }
- //待Lua调用的C注册函数。
- static int add2(lua_State* L)
- {
- //检查栈中的参数是否合法,1表示Lua调用时的第一个参数(从左到右),依此类推。
- //如果Lua代码在调用时传递的参数不为number,该函数将报错并终止程序的执行。
- double op1 = luaL_checknumber(L,1);
- double op2 = luaL_checknumber(L,2);
- //将函数的结果压入栈中。如果有多个返回值,可以在这里多次压入栈中。
- lua_pushnumber(L,op1 + op2);
- //返回值用于提示该C函数的返回值数量,即压入栈中的返回值数量。
- return 1;
- }
- static int sub2(lua_State* L)
- {
- double op1 = luaL_checknumber(L,1);
- double op2 = luaL_checknumber(L,2);
- lua_pushnumber(L,op1 - op2);
- return 1;
- }
- #pragma endregion
- //////////////////////////////////////////////////////////////////////////
- void test_c_call_lua_fun_noParam()
- {
- const char* buff = "print(\"hello\")";
- int err;
- //init
- lua_State* L = luaL_newstate();
- luaL_openlibs(L);
- //load buff
- err = luaL_loadbuffer(L,buff,strlen(buff),"line") ;
- err += lua_pcall(L,0,0,0);
- int s = lua_gettop(L);
- if(err){
- fprintf(stderr,"%s",lua_tostring(L,-1));
- lua_pop(L,1);
- }
- //close
- lua_close(L);
- }
- //////////////////////////////////////////////////////////////////////////
- void test_c_call_lua_fun_withParam()
- {
- lua_State *L = luaL_newstate();
- luaL_openlibs(L);
- if (luaL_loadfile(L, "luafile2.lua") || lua_pcall(L, 0, 0, 0))
- {
- error(L, "cannot run configuration file: %s",lua_tostring(L, -1));
- return;
- }
- lua_getglobal(L, "do_lua_kk");
- lua_getglobal(L, "a");
- lua_getglobal(L, "do_lua_error");
- lua_getglobal(L, "b");
- lua_getglobal(L, "do_c_one");
- lua_getglobal(L, "do_c");
- lua_getglobal(L, "width");
- lua_getglobal(L, "height");
- // lua_getglobal(L, "do_c_two");
- stackDump(L); //打印结果:function `lua_str_a' function `lua_str_b' function function 999 300
- int k = 100;
- k = lua_pcall(L, 2, 1, 1);
- stackDump(L); //打印结果:function `lua_str_a' function `lua_str_b' function 8888
- /*lua 执行栈上最上面的函数,使用栈上2个参数,向栈压入3个返回值
- 使用栈上第1位置的函数do_lua_kk作为错误处理回调函数,输出:
- -------->do_c
- 999--add--300-->--2222
- */
- k = lua_pcall(L, 1, 0, 0);
- stackDump(L);
- lua_close(L);
- }
- //////////////////////////////////////////////////////////////////////////
- void test_c_call_lua_fun_withParam2()
- {
- lua_State* L = luaL_newstate();
- //luaL_dostring 等同于luaL_loadstring() || lua_pcall()
- //注意:在能够调用Lua函数之前必须执行Lua脚本,否则在后面实际调用Lua函数时会报错,
- //错误信息为:"attempt to call a nil value."
- const char* lua_function_code = "function add(x,y) return x + y end";
- if (luaL_dostring(L,lua_function_code)) {
- printf("Failed to run lua code.\n");
- return;
- }
- double x = 1.0, y = 2.3;
- lua_getglobal(L,"add");
- lua_pushnumber(L,x);
- lua_pushnumber(L,y);
- //下面的第二个参数表示带调用的lua函数存在两个参数。
- //第三个参数表示即使带调用的函数存在多个返回值,那么也只有一个在执行后会被压入栈中。
- //lua_pcall调用后,虚拟栈中的函数参数和函数名均被弹出。
- if (lua_pcall(L,2,1,0)) {
- printf("error is %s.\n",lua_tostring(L,-1));
- return;
- }
- //此时结果已经被压入栈中。
- if (!lua_isnumber(L,-1)) {
- printf("function 'add' must return a number.\n");
- return;
- }
- double ret = lua_tonumber(L,-1);
- lua_pop(L,-1); //弹出返回值。
- printf("The result of call function is %f.\n",ret);
- lua_close(L);
- }
- //////////////////////////////////////////////////////////////////////////
- void test_c_use_lua_variant()
- {
- const char* luascript = "width=111 ; height=222";
- lua_State* L = luaL_newstate();
- int w,h;
- //luaL_loadfile的作用是编译lua文件为一个chunk
- //把这个chunk当作一个匿名函数压在栈上
- //lua_pcall的作用是执行这个匿名函数,然后才能取得栈上的值
- if(luaL_loadstring(L,luascript) || lua_pcall(L,0,0,0)){
- printf("Error msg is %s.\n",lua_tostring(L,-1));
- return;
- }
- lua_getglobal(L,"width"); //调用次函数,则把全局变量压栈
- lua_getglobal(L,"height");//这里压栈次序决定了后面取值的索引
- if(!lua_isnumber(L,-2)){
- printf("width must be number\n");
- return;
- }
- if(!lua_isnumber(L,-1)){
- printf("height must be number\n");
- return ;
- }
- w = lua_tointeger(L,-2);
- h = lua_tointeger(L,-1);
- printf("width = %d height = %d\n",w,h);
- lua_close(L);
- }
- //////////////////////////////////////////////////////////////////////////
- void test_c_use_lua_table()
- {
- lua_State* L = luaL_newstate();
- if (luaL_loadstring(L,"background = { r = 0.30, g = 0.10, b = 0 }")
- || lua_pcall(L,0,0,0)) {
- printf("Error Msg is %s.\n",lua_tostring(L,-1));
- return;
- }
- lua_getglobal(L,"background");
- if (!lua_istable(L,-1)) {
- printf("'background' is not a table.\n" );
- return;
- }
- //下面取栈上的table内容
- lua_getfield(L,-1,"r");
- if (!lua_isnumber(L,-1)) {
- printf("Invalid component in background color.\n");
- return;
- }
- int r = (int)(lua_tonumber(L,-1) * 255);
- lua_pop(L,1);//出栈
- lua_getfield(L,-1,"g");
- if (!lua_isnumber(L,-1)) {
- printf("Invalid component in background color.\n");
- return;
- }
- int g = (int)(lua_tonumber(L,-1) * 255);
- lua_pop(L,1);
- lua_pushnumber(L,0.4);//入栈,栈顶位置-1的值是0.4
- lua_setfield(L,-2,"b");//设置background["b"]=0.4,注意-2这个位置表示table的位置!!
- lua_getfield(L,-1,"b");//取table值
- stackDump(L);
- if (!lua_isnumber(L,-1)) {
- printf("Invalid component in background color.\n");
- return;
- }
- int b = (int)(lua_tonumber(L,-1) * 255);
- printf("r = %d, g = %d, b = %d\n",r,g,b);
- lua_pop(L,1);
- stackDump(L);
- lua_pop(L,1); //栈被清空了
- lua_close(L);
- }
- //////////////////////////////////////////////////////////////////////////
- void test_c_new_lua_table()
- {
- lua_State* L = luaL_newstate();
- lua_newtable(L);//Lua会生成一个新的table对象并将其压入栈中。
- lua_pushnumber(L,0.3);
- stackDump(L);//table 0.3
- lua_setfield(L,-2,"r");//设置table["r"]=0.3完了把0.3弹出
- stackDump(L);//table
- lua_pushnumber(L,0.1);
- lua_setfield(L,-2,"g");
- lua_pushnumber(L,0.4);
- lua_setfield(L,-2,"b");
- stackDump(L);//table
- lua_setglobal(L,"background");//栈顶元素出栈
- stackDump(L);//nil
- //调用该宏后,Lua会将当前栈顶的值赋值给第二个参数指定的全局变量名。
- //该宏在执行成功后,会将刚刚赋值的值从栈顶弹出。
- lua_getglobal(L,"background");//把background压栈
- stackDump(L);//table
- if (!lua_istable(L,-1)) {
- printf("'background' is not a table.\n" );
- return;
- }
- lua_getfield(L,-1,"r");//table["r"]压栈
- stackDump(L);//table 0.3
- if (!lua_isnumber(L,-1)) {
- printf("Invalid component in background color.\n");
- return;
- }
- int r = (int)(lua_tonumber(L,-1) * 255);
- lua_pop(L,1);//table
- lua_getfield(L,-1,"g");//table 0.1
- if (!lua_isnumber(L,-1)) {
- printf("Invalid component in background color.\n");
- return;
- }
- int g = (int)(lua_tonumber(L,-1) * 255);
- lua_pop(L,1);//table
- lua_getfield(L,-1,"b");//table 0.4
- if (!lua_isnumber(L,-1)) {
- printf("Invalid component in background color.\n");
- return;
- }
- int b = (int)(lua_tonumber(L,-1) * 255);
- printf("r = %d, g = %d, b = %d\n",r,g,b);
- lua_pop(L,1);//table
- lua_pop(L,1);//nil
- lua_close(L);
- }
- //////////////////////////////////////////////////////////////////////////
- void test_lua_call_c_fun()
- {
- const char* testfunc = "print(add2(1.0,2.0)) print(sub2(20.1,19))";
- lua_State* L = luaL_newstate();
- luaL_openlibs(L);
- //将指定的函数注册为Lua的全局函数变量,其中第一个字符串参数为Lua代码在调用C函数时使用的全局函数名
- //,第二个参数为实际C函数的指针。
- lua_register(L, "add2", add2);
- lua_register(L, "sub2", sub2);
- //在注册完所有的C函数之后,即可在Lua的代码块中使用这些已经注册的C函数了。
- if (luaL_dostring(L,testfunc))
- printf("Failed to invoke.\n");
- lua_close(L);
- }
- //////////////////////////////////////////////////////////////////////////
- //lua文件里的print被C调用时,是可以打印到终端的!!!
- void test_lua_call_c_dll_fun()
- {
- lua_State* L = luaL_newstate();
- luaL_openlibs(L);
- if(luaL_dofile(L,"lua_call_c.lua"))
- printf("load lua_call_c.lua failed\n");;
- lua_close(L);
- }
- #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}
- };
- 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_newlib(L,arraylib_m);
- //这里只注册的工厂方法。
- luaL_newlib(L,arraylib_f);
- return 1;
- }
- int main()
- {
- test_c_call_lua_fun_noParam();
- test_c_call_lua_fun_withParam();
- test_c_call_lua_fun_withParam2();
- test_c_use_lua_variant();
- test_c_use_lua_table();
- test_c_new_lua_table();
- test_lua_call_c_fun();
- test_lua_call_c_dll_fun();
- getchar();
- return 0;
- }
lua52 C API测试代码的更多相关文章
- API 测试的具体实现
目录 API 测试的具体实现 基于 Spring Boot 构建的 API 使用 cURL 命令行工具进行测试 使用图形界面工具 Postman 进行测试 如何应对复杂场景的 API 测试? 总结 A ...
- Go项目的测试代码2(项目运用)
上一篇文章介绍了最基本的测试代码的写法.Go项目的测试代码(基础) 这里简单的共享一下我在项目中使用的方式. 项目结构 我们实际项目中, 结构简单地分了控制层controllers和模块层models ...
- .NET单元测试的艺术-3.测试代码
开篇:上一篇我们学习单元测试和核心技术:存根.模拟对象和隔离框架,它们是我们进行高质量单元测试的技术基础.本篇会集中在管理和组织单元测试的技术,以及如何确保在真实项目中进行高质量的单元测试. 系列目录 ...
- 使用python+pychram进行API测试(接口测试)初级STEP 1
花了一天时间安装了解了下最基本的python+pychram进行API测试,下面这个可以指导自己以后入门:基本的开发级别还需要学习 1.python下载地址:https://www.python.or ...
- asp.net web api 测试帮助页面建立并测试
asp.net web api 测试帮助页面建立并测试 现在使用WEB API来开发,越来越流行. 在开发过程中的测试调试,可以使用Fiddler等工具来帮助测试外,还有: 在asp.net 中有种方 ...
- API测试自动化——基于CDIF的SOA基本功能(实例篇)
今天我们通过一些实例来体验一下API的自动化测试,感受一下基于CDIF的SOA的一些基本功能. 传统的测试工具在测试一个API的时候,必须手动填写这个API所需要接收的所有信息,比如一个查询航班动态的 ...
- 开源API测试工具 Hitchhiker v0.6更新 - 改进压力测试
Hitchhiker 是一款开源的支持多人协作的 Restful Api 测试工具,支持Schedule, 数据对比,压力测试,支持上传脚本定制请求,可以轻松部署到本地,和你的team成员一起协作测试 ...
- 开源API测试工具 Hitchhiker v0.7更新 - Schedule的对比diff
Hitchhiker 是一款开源的支持多人协作的 Restful Api 测试工具,支持Schedule, 数据对比,压力测试,支持脚本定制请求,可以轻松部署到本地,和你的team成员一起协作测试Ap ...
- 开源API测试工具 Hitchhiker v0.8 - 自动化测试结果统计
Hitchhiker 是一款开源的支持多人协作的 Restful Api 测试工具,支持自动化测试, 数据对比,压力测试,支持脚本定制请求,可以轻松部署到本地,和你的team成员一起协作测试Api. ...
随机推荐
- 1 云计算系列之云计算概述和KVM虚拟化简介
为什么会出现云之传统数据中学面临的问题 物理服务器的利用率非常低,浪费资源,且资源分配不合理,比如一台服务器CPU使用率不到40%,或者某个应用需要的硬件配置低但是服务器硬件配置高等等. 云计算概念 ...
- <<< Oracle表空间创建、修改、删除基本操作
ORACLE 中,表空间是数据管理的基本方法,所有用户的对象要存放在表空间中,也就是用户有空间的使用权,才能创建用户对象 create tablespace myts //建立表空间,名为mytsd ...
- Socket异步通讯
1.可以通过多线程来解决(一会补上) 2.Socket在tcp/udp两种通信协议下的异步通信: 基于TCP的异步通信: BeginAccept方法和endeaccept方法 包含在System.Ne ...
- Redis主-从部署实践
0. 前言 这篇文章简要介绍Redis的主从部署,实现了一主二从,使用两个哨兵监控,以实现简单的HA,其中从库作为备机. 1. 部署 这里有三台服务器,其中239主机上的Redis作为主库,其余两个作 ...
- Unable to load configuration. - Class: java.net.AbstractPlainSocketImpl
[Bug笔记]Unable to load configuration. - Class: java.net.AbstractPlainSocketImpl 标签: bugjartomcat服务器互联 ...
- Centos6.5 Zabbix3 server端安装(一)
一.准备阶段: 1.>关闭防火墙 /etc/init.d/iptables stop 2.>关闭selinux vim /etc/selinux/config SELINUX=disabl ...
- FireFox每次访问页面时检查最新版本
FireFox每次访问页面时检查最新版本 浏览器都有自己的缓存机制,作为开发人员,每次js的修改都要清空缓存,显然很不方便.而firefox并没有提供ie那样的设置. 下面的方法就可以非常方便的设置f ...
- 学习MySQL之单表操作(二)
##单表操作 ##创建表 CREATE TABLE t_employee( empno ), ename ), job ), MGR ), Hiredate DATE DEFAULT '0000-00 ...
- 【piu~】制作一只变形小鸡~
在http://codepen.io/pick上看到的,,,具体是谁忘了,反正我只截了最萌的一段,作者越改越不萌ಥ_ಥ 谷哥哥随便一搜就有很多好玩的,度娘就...(  ̄ ▽ ̄)o╭╯☆#╰ _─﹏─) ...
- 微信公众平台"微信连Wi-Fi"功能来了 线下微信增粉利器
微信连Wi-Fi功能在第三方开发者和服务商已经有出现了,但有些成本相对会高些.近日微信公众平台新添了一个功能插件“微信连Wi-Fi”,已有微信认证过的公众号即可申请开通.赶紧去布局这个线下微信增粉利器 ...