Windows下

我用的是vs2019,由于Windows下不像Linux可以直接直接安装lua程序直接运行lua代码,所以这里我们演示的是,通过c/c++调用lua脚本,lua脚本再调用其他的C/C++文件。

先用vs2019创建一个windows桌面向导–控制台程序的工程

注意是选择windows桌面向导,项目名称必须是luaclib,到时候生成的dll文件为luaclib.dll,后边lua层用require调用c模块的时候dll文件的名称很重要。

一班的动态库都需要.cpp和.h文件,但对于lua调用C/C++,不用.h文件也行, 这里我们为了正规一点,.cpp和.h一起用

在开始之前,我们需要了解,lua5.1之后,lual_register()就被舍弃了,使用
lua_newtable(L);
luaL_setfuncs(L, myLib, 0);
一起使用来进行替代。
为了大家能够更深的理解,对于Windows下的lua调用C/C++模块,我们采用了lua5.1版本的方式,也就是使用lual_register()来进行测试;
在Linux环境下,我们采用lua5.2版本(即使用lua_newtable(L);
luaL_setfuncs(L, myLib, 0);来测试)

首先是windows下

luaclib.h

#pragma once#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>#ifdef _LUA_EXPORTS
#define LUA_API __declspec(dllexport)
#else
#define lUA_API __declspec(dllimport)
#endif//extern "C" LUA_APIint luaopen_luaclib(lua_State * L);  //定义导出函数

luaclib.cpp


#include <stdio.h>
#include "luaclib.h"static int averageFunc(lua_State* L) {int n = lua_gettop(L);double sum = 0;int i;//循环参数求和for (i = 1; i <= n; i++) {sum += lua_tonumber(L, i);}lua_pushnumber(L, sum / n);  //压入平均值lua_pushnumber(L, sum); // 压入和return 2;  //返回两个结果
}static int sayHelloFunc(lua_State* L) {printf("hello world!");return 0;
}static const struct luaL_Reg myLib[] = {{"average", averageFunc},{"sayHello", sayHelloFunc},{NULL, NULL}
};int luaopen_luaclib(lua_State* L) {//其函数名必须为luaopen_xxx,其中xxx表示library名称。Lua代码require "xxx"需要与之对应//所以这里生成的dll必须是luaclib.dllluaL_register(L, "ss", myLib); -- lua5.1版本及以前使用/*lua_newtable(L);luaL_setfuncs(L, myLib, 0);*/  --lua5.1之后的版本return 1;
}

将这个工程编译成.dll文件,可在创建工程的时候选择生成.dll文件,若忘记选择了,也可使用下图的方式设置后,将工程重新编译生成.dll文件。

不出意外得到的dll文件为luaclib.dll。
至此动态库就准备好了,这个动态库就是我们后边要用lua来调用的C++模块。

接下来重新创建一个工程,并且需要把上边得到的.dll 文件放到这个工程下。
新建两个文件,一个test.cpp. 一个hello.lua
test.cpp

#include <iostream>
#include <lua.hpp>
/*相当于#include <lua.hpp>
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
*/using namespace std;
int main() {lua_State* L = luaL_newstate(); //lua_open();luaL_openlibs(L);   //必不可少//加载lua文件int bRet = luaL_loadfile(L, "hello.lua");if (bRet) {cout << "load file error" << endl;return  0;}//运行lua文件bRet = lua_pcall(L, 0, 0, 0);if (bRet) {cout << "pcall error" << endl;return  0;}return 1;
}

hello.lua

require "luaclib"
local avg,sum =ss.average(1,2,3,4,5)
print(avg,sum)  -- 3 15
ss.sayHello()   -- hello world!

到此为止,项目已经可以运行测试, 前提是配置好了lua环境,也就是一些头文件的引用,以及库文件的引用,如果你是新手,lua运行环境配置,去这篇文章配置好环境。

Linux下

Linux下就很简单了,因为可以在控制台上直接运行lua程序
需要一个.c文件作为被调用的模块, 以及一个.lua文件
test.c 其实和上边windows的test.c几乎一样,代码末端有区别。

#include<stdio.h>
#include<lua.h>
#include<lauxlib.h>
#include<lualib.h>static int averageFunc(lua_State* L) {int n = lua_gettop(L);double sum = 0;int i;//循环参数求和for (i = 1; i <= n; i++) {sum += lua_tonumber(L, i);}lua_pushnumber(L, sum / n);    //压入平均值lua_pushnumber(L, sum); // 压入和return 2;  //返回两个结果
}static int sayHelloFunc(lua_State* L) {printf("hello world!");return 0;
}static const struct luaL_Reg myLib[] = {{"average", averageFunc},{"sayHello", sayHelloFunc},{NULL, NULL}
};
//该C库的唯一入口函数。其函数签名等同于上面的注册函数。见如下几点说明:
//1. 我们可以将该函数简单的理解为模块的工厂函数。
//2. 其函数名必须为luaopen_xxx,其中xxx表示library名称。Lua代码require "xxx"需要与之对应。
//3. 在luaL_setfuncs的调用中,其第二个参数为待注册函数的数组。
//4. 需要强调的是,所有需要用到"xxx"的代码,不论C还是Lua,都必须保持一致,这是Lua的约定,
//   否则将无法调用。
int luaopen_luaclib(lua_State* L)
{//const char* libName = "mytestlib"; ////luaL_register(L, libName, mylib); //由于在lua-5.2中已没有luaL_register这个函数,所以换成下面两行代码lua_newtable(L);luaL_setfuncs(L, myLib, 0);return 1;
}

test.lua

#!/usr/local/bin/lua //有了这行命令,可以直接 ./test.lua 运行lua程序
local mylib = require("luaclib")  --对应于teste.c中的包名
local avg,sum =mylib.average(1,2,3,4,5)
print(avg,sum)  -- 3 15
mylib.sayHello()   -- hello world!

需要把test.c文件编译成一个动态库
gcc -o luaclib.so -fPIC -shared test.c

  1. -shared,众所周知啊,.so时share object的缩写。为了让gcc知道是在编译 .so而不是可执行文件,所以需要-shared

  2. -fPIC,这是编译动态库必须的。可见黄色圈起来的地方,分开编译,没加-fPIC,就会报错,提醒重新编译。其实-fPIC是编译选项,PIC是 Position Independent Code 的缩写,表示要生成位置无关的代码,这是动态库需要的特性。

这里必须是gcc, 不能用g++, g++是用在cpp文件中的。
建议你先不要用cpp文件,和我一样,先用c文件测试成功后再尝试cpp,因为cpp涉及了extern ”c”的使用,不然函数名字导出成动态库的时候会出错。

使用命令, lua test.lua 即可看到效果。
如果lua文件中添加了#!/usr/local/bin/lua, 可直接 ./test.lua

上边这种是调用的c模块,如果是c++模块有一点小区别, 必须要使用extern"C", 它的作用是告诉系统以c语言的方式来导出动态库文件,我们都知道c++有函数重载这个说法,所以,在c++中的动态库的函数名字与c语言中是不一样的,因为c++中可能出现同名函数,所以c++在导出的动态库中对函数名进行了一些额外的标志,所以我们需要用到extern“C”来以C语言的方式导出

只需把上边的test.c 改为 test.cpp
test.cpp

#include<stdio.h>
#include<string.h>
extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
extern "C" {
static int averageFunc(lua_State* L) {int n = lua_gettop(L);double sum = 0;int i;//循环参数求和for (i = 1; i <= n; i++) {sum += lua_tonumber(L, i);}lua_pushnumber(L, sum / n);    //压入平均值lua_pushnumber(L, sum); // 压入和return 2;  //返回两个结果
}
static int sayHelloFunc(lua_State* L) {printf("hello world!");return 0;
}
static const struct luaL_Reg myLib[] = {{"average", averageFunc},{"sayHello", sayHelloFunc},{NULL, NULL}
};
int luaopen_mytestlib(lua_State* L)
{lua_newtable(L);luaL_setfuncs(L, myLib, 0);return 1;
}
}

区别就是加了extern“C“ ,然后将命令改成
g++ -o luaclib.so -fPIC -shared test.c (上边用的是gcc)

编译好的动态库静态库资源
链接:https://pan.baidu.com/s/1hbLQm508bV-8PNgO6qiG1A?pwd=200v
提取码:200v

这里只是lua调用C/C++,去这一篇学习 C/C++ 如何调用lua(点我)
如遇任何问题,欢迎评论区留言~

Lua脚本如何调用C/C++模块,Windows以及Linux版本演示相关推荐

  1. C/C++ 如何调用Lua脚本,Windows以及Linux版本演示

    分为linux下和windows平台下: 前置工作,准备好lua安装包. 方法一(linux): 依次使用以下命令 得到安装包: wget http://www.lua.org/ftp/lua-5.2 ...

  2. linux c程序调用脚本,C程序与Lua脚本相互调用

    Lua脚本是一种可用于C程序开发/测试的工具,本篇介绍一下C程序与Lua脚本如何进行相互调用,更加详细的操作参见<Programing in Lua>.本文分为3个部分:1.Windows ...

  3. matlab R2010a windows和linux版本下载地址

    matlab R2010a windows和linux版本下载地址: win:ed2k://|file|[%E7%9F%A9%E9%98%B5%E5%AE%9E%E9%AA%8C%E5%AE%A4]. ...

  4. 超详细anaconda安装教程(Mac,Windows,Linux版本)

    超详细anaconda安装教程(Mac,Windows,Linux版本) Windows系统安装Anaconda macOS系统安装Anaconda Linux系统安装Anaconda Windows ...

  5. 实战:Nginx集成Lua脚本并调用memcached

    之前在阿里云的centos系统上已经安装过nginx,但是没有安装lua所需的模块,因此重新编译nginx来扩展lua模块. ngx_lua_module 是一个nginx http模块,它把 lua ...

  6. linux达芬奇安装教程,[正版]Windows/Mac/Linux版本-达芬奇调色软件DaVinci Resolve v11.1.2(正式版+Lite)...

    [软件介绍] 专业的达芬奇调色软件又更新啦!DaVinci Resolve v11.1.2 注:正式版和Lite 版本区别:有无降噪功能,是否支持2K以上分辨率工程 软件语言为:中文,英文,日文. 软 ...

  7. cmake构建器最新Windows/MACOS/LINUX版本分享

    各个平台版本如下,会持续更新. cmake-3.17.5-Darwin-x86_64.dmg cmake-3.17.5-Linux-x86_64.sh cmake-3.17.5-win32-x86.m ...

  8. LUA脚本调用C场景,使用C API访问脚本构造的表

    LUA调用C lua解析中集成了一些系统服务, 故脚本中可以访问系统资源, 例如, lua脚本可以调用文件系统接口, 可以调用数学库, 但是总存在一些lua脚本中访问不到的系统服务或者扩展功能, 如果 ...

  9. 【笔记】cocos2dx xxtea逆向获取lua脚本和资源文件

    参考链接: https://blog.csdn.net/cjbbdd/article/details/103583764 使用的一些注意点,链接中未提到的: 1.NDK版本: 使用的ndk版本为r9d ...

最新文章

  1. 2021年大数据常用语言Scala(三十八):scala高级用法 隐式转换和隐式参数
  2. 数据结构与算法(6-4)线索二叉树
  3. html 页面宽度和背景颜色,CSS:设置背景颜色为窗口宽度的50%
  4. python opengl 入门
  5. CDN简介及linux环境下搭建
  6. SAP HANA中的SLT简介
  7. php curl https 443,PHP CURL支持HTTP、HTTPS 请求亲测可用
  8. java转换为字符串_java – 如何从int转换为字符串?
  9. select中option解析
  10. Google Chrome 1.0.154.46稳定版本发布 修复高危安全漏洞
  11. 最常被利用的三大 API 漏洞:是什么、为什么、如何阻止?
  12. Python+Visual Studio
  13. call需要多大带宽 video_从游戏的发展趋势看,未来显存多大能够用?
  14. 《白帽子讲Web安全》| 学习笔记之访问控制
  15. 你知道视频去水印的方法有哪些吗?分享2个实用的去水印方法
  16. linux 桌面美化指南,Linux_9方面立体式地美化Ubuntu桌面,总结了一下桌面美化的设置。 - phpStudy...
  17. 少儿编程微课程14:对称图形的模拟验证
  18. python cpu温度_使用Python(和其他一些不错的技巧)检查CPU的温度
  19. HiveSQL中级进阶常用技巧
  20. Campus Talking 小记(3)

热门文章

  1. 请你说说进程、线程、纤程之间的区别?
  2. 高通转单台积电,联发科的高端梦悬了
  3. Bp神经网络预测中trainlm算法和trainbr算法的应用
  4. 对外贸易市场前景被看好,离岸账户开户需求日渐增长
  5. 骨传导耳机是怎么传声的、骨传导耳机的优点是什么
  6. tabBar的简单使用,以及扩展
  7. 10大网络美女排行榜(组图)(*^__^*) ……
  8. Word 2016 撰写论文(5): MathType 矩阵中的每个元素居中对齐
  9. element 表单只允许输入数字和两位小数,保留两位小数(四舍五入) 小数不足两位补0
  10. JAVA通幽(八)正则表达式