lua與c++交互lua5.3調用dll-64位

        公司所用的框架是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 <iostream>  
#include <Windows.h> 
#include <vector>
#include <set>
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<string> Permutation(string str, vector<string>&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<string> all_str;
};

//全排列算法
extern "C" int AllSort(lua_State* L)
{
	

	// 提取參數.  
	const char* str= luaL_checkstring(L, 1);

	if (str)
	{
		Solution sln;
		vector<string> 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<string> strResult;
        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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章