博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Lua学习笔记-C API
阅读量:4983 次
发布时间:2019-06-12

本文共 2819 字,大约阅读时间需要 9 分钟。

学习Lua的最终目的就是为了和C/C++互调,所以C API是承上启下的重头戏。

核心思想:Lua与C通过一个抽象的栈进行通信。你可以理解为Lua和C各司其职,只是通过栈进行沟通,类似操作系统的进程通讯一样。这样做至少有两点好处:1. 程序员不必关心另一个语言是如何工作的,只需要清楚有哪些值是自己需要的  2. 避免类型不一致或者动态内存管理带来的问题,因为C需要手动管理内存,而Lua有自动垃圾回收机制。

关于栈需要了解下面两点:

1. 栈中的严格遵循FIFO,栈底索引为1,栈顶索引为栈中元素个数。另外负数表示从栈顶开始索引,通常用-1方便的获取栈顶元素。

2. Lua的所有C API都是针对栈顶元素进行操作,这里不是说不能修改栈中的值,而是所有的值只能从栈中获取。每次操作可能是获取/修改值,也可能弹出栈顶元素或者压入元素,具体可以参考。英文不好的也可以参考一下这篇博客,虽然排版有点混乱。

 

C调用Lua

关于Lua的C API,网上有很多教程,官方文档也很详细,这里不再记录。直入主题,在具体例子中解释。

首先编写一个简单的lua脚本文件t.lua。内容如下

1 int=1 2 double=1.23456 3 s='string' 4 bool=true 5 table={
1,2,3,n=4} 6 7 function add(a,b) 8 print("a="..a,"b="..b) 9 return a+b10 end11 12 function printTable(t)13 for i,v in pairs(t) do14 print(i,v)15 end16 end

 

这里声明了Lua中常用的几种值类型,number,string,boolean,table,function,目的是C代码中对这些值进行操作,能比较全面的了解一下。

下面是调用lua的C文件,不明白extern的作用可以参考这篇

1 #include 
2 #include
3 #include
4 using namespace std; 5 6 //引用lua库 7 #ifdef _DEBUG 8 #pragma comment(lib,"D:\\lua\\luaforwindows-master\\files\\lib\\lua51.lib") 9 #pragma comment(lib,"D:\\lua\\luaforwindows-master\\files\\lib\\lua5.1.lib")10 #endif11 12 extern "C"13 {14 #include
15 #include
16 #include
17 }18 19 int errorMsg(int error); //打印错误信息20 21 lua_State *L = lua_open(); /* opens Lua */22 23 int main(void)24 {25 int error;26 luaL_openlibs(L);27 28 error = luaL_loadfile(L, "E:/lua project/t.lua"); //载入lua脚本作为chunk入栈,但不运行29 if (errorMsg(error))30 return 0;31 32 error = lua_pcall(L, 0, 0, 0); //运行栈中的chunk33 if (errorMsg(error))34 return 0;35 36 lua_getglobal(L, "int"); //找到t.lua中的全局变量int压入栈中,下面类似37 lua_getglobal(L, "double");38 lua_getglobal(L, "s");39 lua_getglobal(L, "bool");40 41 for (int i = 1; i < lua_gettop(L); i++) //打印栈中除table元素,所有值均可转为string42 cout << lua_tostring(L, i) << endl;43 44 lua_getglobal(L, "printTable"); //找到printTable函数入栈45 lua_getglobal(L, "table"); //将参数table入栈46 error = lua_pcall(L, 1, 0, 0); //调用printTable函数47 if (errorMsg(error))48 return 0;49 50 lua_getglobal(L, "add"); //找到add函数入栈51 lua_pushnumber(L, 10); //压入第一个参数52 lua_pushnumber(L, 20); //压入第二个参数53 error = lua_pcall(L, 2, 1, 0); //调用add函数54 if (errorMsg(error))55 return 0;56 57 cout << "result=" << lua_tostring(L, -1); //打印返回值58 59 return 0;60 }61 62 int errorMsg(int error)63 {64 if (error)65 {66 const char *pErrorMsg = lua_tostring(L, -1);67 cout << pErrorMsg << endl;68 return 1;69 }70 return 0;71 }

 

 

Lua调用C

参考了一下网上的方案,发现一篇写的很详细的博客,个人比较懒,不再赘述。

这里面第三种方法比较常用,但是涉及到其他知识。所以我整理了一下相关的资料:

1.

2.

3.

这里面有一个坑,那就是如果不想将DLL文件复制到脚本目录下,而采用绝对路径链接的时候,修改的应该是package.cpath=“.../xx.dll”,而不是path,如果修改的是path是无法正确读取动态链接库的。

比如

package.cpath="C:/Users/Documents/visual studio 2013/Projects/mylib/Debug/?.dll"require "mylib"

 

转载于:https://www.cnblogs.com/InitialD/p/7424154.html

你可能感兴趣的文章
2017-11-6 Django
查看>>
图像处理中的matlab使用
查看>>
动态规划 —— 背包问题一 专项研究学习
查看>>
51nod 1571 最近等对 | 线段树 离线
查看>>
关于parseInt的看法
查看>>
从用户端到后台系统,严选分销教会我这些事
查看>>
数据分析融入至BI工具的新思路
查看>>
微服务实践沙龙-上海站
查看>>
Ubuntu中Could not get lock /var/lib/dpkg/lock解决方案
查看>>
c#必会知识点
查看>>
网页使用MD5加密
查看>>
JS 基础
查看>>
HBase shell 中的十六进制数值表示
查看>>
Matlab产生TestBeach所需要的波形数据
查看>>
Python3 中 configparser 模块解析配置的用法详解
查看>>
debian的python蓝牙库
查看>>
新手android环境搭建、debug调试及各种插件安装__图文全解
查看>>
未在本地计算机上注册“Microsoft.Jet.OLEDB.4.0”提供程序 win2008R2 X64 IIS7.5
查看>>
Diffuse贴图+Lightmap+Ambient
查看>>
[Linux内存]slab分配器学习笔记(二)--slab着色
查看>>