项目背景:
因为lua是单线程的,每个lua执行就相当于是一个线程,因此是没有办法完成调用两个C线程的,不能满足当前项目需求,因此不使用lua脚本的方式进行CDLL的线程调用管理了,而使用python了。
1、 lua基础
https://www.runoob.com/lua/lua-tutorial.html
--两个点表示连接
print("两个点表示连接")
a = "1212" .. "nihao"
print(a)
--测试function及for和if语法
print("测试function及for和if语法")
local function maxs(a)
local maxi = 1
local maxnum = a[maxi]
for i, val in ipairs(a) do
if val > maxnum then
maxi = i
maxnum = val
end
end
return maxi, maxnum
end
print(maxs({8,10,23,12,5,0}))
--table的concat测试
local fruits = {"banana", "orange", "apple"}
print("连接后的字符串", table.concat(fruits))
print("指定连接字符后的字符串", table.concat(fruits, ", "))
print("指定索引来连接table的字符串", table.concat(fruits, ", ", 2, 3))
--测试函数传参可变参数
print("测试函数传参可变参数")
function add(...)
local s = 0
local arg = {...}
for i, v in ipairs{...} do --> {...} 表示一个由所有变长参数构成的数组
s = s+v
end
print("总共传入 " .. select("#",...) .. " 个数")
print("传入" .. #arg .. "数字")
return s
end
print(add(1,2,3,4,5,6,7,0))
--获取参数总数
function foo(...)
for i = 1, select('#', ...) do
local arg = select(i, ...) --> select(n,…) 可以访问第 n 个到数组最后的参数
print("arg", arg)
end
end
print(foo(1,2,3,4))
--运算符.. #
a = "Hello "
b = "World"
print("连接字符串 a 和 b ", a..b )
print("b 字符串长度 ",#b )
--测试模块
《module.lua文件》
module = {}
module.constant = "这是一个变量"
function module.func1()
io.write("这是一个公有函数!\n")
end
local function func2()
print("这是一个私有函数")
end
function module.func3()
func2()
end
return module
《main.lua文件》
local m = require("module") --> 别名
m.func1();
m.func3();
print(m.constant)
--测试元表的__index
print("测试元表的__index")
mytable = setmetatable({key1 = "value1"}, {__index = {key2 = "metatablevalue"}})
print(mytable.key1, mytable.key2)
--测试元表的相加
function table_maxn(t)
local mn = 0
for k, v in pairs(t) do
if mn < k then
mn = k
end
end
return mn
end
mytable = setmetatable({1, 2, 3}, {
__add = function(mytable, newtable)
for i = 1, table_maxn(newtable) do
table.insert(mytable, table_maxn(mytable)+1, newtable[i])
end
return mytable
end
})
secondtable = {4, 5, 6}
mytable = mytable + secondtable
for k, v in ipairs(mytable) do
print(k, v)
end
2、 C调用lua,执行lua脚本
复制lua源码到工程中或者引入lua的lib文件及头文件也可。
#include <windows.h>
extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
int main()
{
lua_State* l = luaL_newstate();
luaL_openlibs(l);
luaL_dofile(l, "main.lua");
lua_close(l);
system("pause"); //为了保证在windows资源管理器中打开main.exe不闪退。需要windows.h。
return 0;
}
3、lua调用C库
c工程
extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
};
#include <thread>
#include <iostream>
using namespace std;
int number = 0;
int number2 = 0;
int flag = 0;
std::thread *t1 = NULL;
std::thread *t2 = NULL;
void ThreadProc1()
{
flag = 1;
while (1)
{
cout << "thread 1 :" << number << endl;
++number;
this_thread::sleep_for(std::chrono::milliseconds(10));
}
return ;
}
void ThreadProc2()
{
while (number2 < 100)
{
cout << "thread 2 :" << number2 << endl;
++number2;
this_thread::sleep_for(std::chrono::milliseconds(10));
}
return ;
}
extern "C" int ShowMsg(lua_State* luaEnv) {
cout << "Hello world from clibs!" << endl;
t1 = new std::thread(ThreadProc1);
return 1; // 返回值个数为0个.
}
extern "C" int ShowMsg2(lua_State* luaEnv) {
cout << "Hello world from clibs222!" << endl;
t2 = new std::thread(ThreadProc2);
return 0; // 返回值个数为0个.
}
// part one: 要导出的函数列表
static luaL_Reg luaLibs[] = {
{ "ShowMsg", ShowMsg },
{ "ShowMsg2", ShowMsg2 },
{ NULL, NULL }
};
// part two: DLL入口函数,Lua调用此DLL的入口函数.
//testDll是modole名, 将来require这个名字并且这个名称要与dll名称一致,并且不能与lua名称一致
extern "C" __declspec(dllexport)
int luaopen_testDll(lua_State* luaEnv) {
const char* const LIBRARY_NAME = "WinFeature"; //这里也写WinFeature
luaL_register(luaEnv, LIBRARY_NAME, luaLibs);//注册要导出的函数列表
return 1;
}
lua文件
--加载test库
WinFeature1 = require("testDll")
--定义协程
co = coroutine.create(
function()
WinFeature1.ShowMsg()
end
)
--激活协程
coroutine.resume(co)
--打印协程状态
print(coroutine.status(co))
4、lua无法调起C库中两个线程,以及lua端卡死问题或者lua端协程结束C也跟着结束
lua函数
--加载test库
WinFeature1 = require("testDll")
function Sleep(n)
local t0 = os.clock()
while os.clock() - t0 <= n do end
end
--定义协程
co = coroutine.create(
function()
WinFeature1.ShowMsg()
while true do
print("coroutine")
Sleep(0.1)
end
end
)
--激活协程
coroutine.resume(co)
--打印协程状态
print(coroutine.status(co))
参考博客:
https://blog.csdn.net/qq_35807952/article/details/79912769 Lua与C++交互初探之Lua调用C++
https://www.runoob.com/lua/lua-tutorial.html Lua 教程
https://www.cnblogs.com/chechen/p/11415104.html VS2015 创建C++动态库及使用
https://blog.51cto.com/u_1433795/1310702 lua 调用C++ DLL函数简单实例
https://www.kancloud.cn/thinkphp/lua-guide/43809 绑定Lua和C/C++的库
检测动态库中导出的函数列表
dumpbin /exports testDll.dll