公司所用的框架是skynet,是c-lua语言,有时lua效率不够,又有现成的大量的C++算法,所以我就有了研究一下lua调用C++的想法,以供不备之需,准备环境是windows7,vs2013,vscode,vscode插件-Lua Debug, Lua Debugger,EmmyLua,插件是方便调试开发用的,vscode对lua5.3-64位支持比较好,建议还是用vscode好一点。
extern "C" {
#include "lua.hpp"
#include "lauxlib.h"
#include "lualib.h"
};
#pragma comment(lib, "lua.lib")
#include
#include
#include
#include
using namespace std;
我看到很多朋友的教程没有#pragma comment(lib, "lua.lib")这一段,对于新手来说他是编译通不过的,因为不在这里加,去配置工程有点罗嗦,上面的头文件,dll,lib都不用下载了,我这都包含了,直接下载我上传的工程就行了,注意工程一定要选择64位的,lua那边也要对应是64位的lua,反正两边要相同,两边32位的也行,否则会报error load,无效win2程序。。首先我先试试普通的函数传参行不行,
extern "C" int sub2(lua_State* L)
{
double op1 = luaL_checknumber(L, 1);
double op2 = luaL_checknumber(L, 2);
int temp = op1 - op2;
lua_pushnumber(L, temp);
return 1;
}
// 导出函数列表.
static luaL_Reg luaLibs[] =
{
{ "ShowMsgBox", ShowMsgBox },
{ "sub2", sub2 },
{ "AllSort", AllSort },
{ "lua_get_info", lua_get_info },
{ NULL, NULL }
};
// part two: DLL入口函数,Lua调用此DLL的入口函数.
extern "C" __declspec(dllexport)
int luaopen_WinFeature(lua_State* L) { //WinFeature是modole名, 将来require这个名字
const char* const LIBRARY_NAME = "WinFeature"; //这里也写WinFeature
//luaL_register(L, LIBRARY_NAME, luaLibs); //关键一行, 在luaState上注册好这个lib
lua_newtable(L);
luaL_setfuncs(L, luaLibs,0);
return 1;
}
定义extern "C" int sub2(lua_State* L),一定是要C类型函数。注册C函数,lua5.3和旧的又不相同,现在注册函数是这个了luaL_setfuncs(L, luaLibs,0),再来看lua调用代码:
编译生成的dll一定要放在和lua文件一个目录,WinFeature.dll,lua.dll。
local WinFeature=require "WinFeature"
print(WinFeature.sub2(1,2));
就是这么简单,调用一下就ok了,那么接下来试试C++数组类型如何返回给lua,我刚好写了个全排列算法的例子,往下看,
class Solution {
public:
vector Permutation(string str, vector&result) {
loc_Permutation(str, 0);
if (str.size() == 0)return result;
for (auto item : all_str){
result.push_back(item);
}
//result = all_str;
return result;
}
void loc_Permutation(string str, int loc){
all_str.insert(str);
//all_str.push_back(str);
//cout << str << endl;
int size = str.size();
if (loc == size - 1)return;
//loc_Permutation(str, loc + 1);
for (int idx_swap = loc; idx_swap < size; idx_swap++){
//cout << loc << " " << idx_swap << " ";
swap(str[loc], str[idx_swap]);
loc_Permutation(str, loc + 1);
swap(str[loc], str[idx_swap]);
}
}
public:
set all_str;
};
//全排列算法
extern "C" int AllSort(lua_State* L)
{
// 提取参数.
const char* str= luaL_checkstring(L, 1);
if (str)
{
Solution sln;
vector strResult;
strResult = sln.Permutation(str, strResult);
//lua_settop(L, 0);
lua_newtable(L);
lua_newtable(L);
int count = 1;
for (int i = 0; i < strResult.size();i++)
{
lua_pushstring(L, strResult[i].c_str());
//lua_setfield(L, -2, i);
lua_rawseti(L, -2, count++);
}
//嵌套school表到参数表中
lua_pushstring(L, "array");
lua_insert(L, -2); /* school table */
lua_settable(L, -3); /* param.school = school */
//return strResult.size();
}
else
{
ErrorMsg(L, ERROR_ARGUMENT_TYPE);
}
// 返回值个数为0个.
return 1;
}
Solution sln;
vector
strResult = sln.Permutation(str, strResult);
在C接口里面调用C++对象进行算法处理,得到结果返回给lua,这个是比较简单的用法。
关键写法:
for (int i = 0; i < strResult.size();i++)
{
lua_pushstring(L, strResult[i].c_str());
//lua_setfield(L, -2, i);
lua_rawseti(L, -2, count++);
}
他的功能相当于生成表{[1]=strResult[i],[2]=strResult[i]...........}
lua_pushstring(L, "array");
lua_insert(L, -2);
lua_settable(L, -3);
这三句相当于是把上面的表赋给array;
看一下调试结果
至此简单的lua调用C++模块的交互已经完成了,更加复杂的lua里面像面向对象一样使用C++的推荐另外一篇文章https://www.cnblogs.com/sifenkesi/p/3897245.html
上面示例工程资源下载链接https://download.csdn.net/download/huangdecai2/12399268
有更加好想法的伙伴,可以加我一起交流学习,q460000713