编译
- 编译lua.lib时工程不包含luac.c文件,
- 编译luac时工程包含luac.c文件但是不包含lua.c文件。
封装注册Lua C API
Lua原生态逐个函数注册
- lua_register(L, “test”, test)
数组批量注册
#define MODULE_NAME_STAR "star"
extern const struct luaL_Reg starlib[] = {
{"msgbox", msgbox},
{"log", log},
{"md5", md5},
{"trim", trim},
//……
};
int openMyLuaLib(lua_State *L) {
luaL_newlibtable(L, starlib);
lua_pushvalue(L, -1);
luaL_setfuncs(L, starlib, 0);
return 1;
}
luaL_requiref(L, MODULE_NAME_STAR, openMyLuaLib, 1);
使用luabind
需要注意的是,使用luabind注册导出类时,类的构造函数需要一并导出,否则可能会导致崩溃问题。
luabind::open(L);
module(L)
[
def( "msgbox", &msgbox),
def( "dbgprint", &dbgprint)
//class_<CClientControl>("CMyClass")
//.def(constructor<>())
//.def("testFunc1", &CMyClass::testFunc1)
//.def("testFunc2", &CMyClass::testFunc2)
];
C函数就要按如下封装:
int msgbox(const char*szText) {
return ::MessageBoxA(0,szText,NULL,0);
}
注意: 返回值类型和参数类型必须是常见的数据类型,例如:int,long,DWORD,string,char*都是可以的, 结构体或者其他类型指针不支持。而且这里的返回值不再表示返回值个数,就代表返回值。
C/C++执行Lua脚本
- luaL_dofile
- luaL_loadbuffer
extern "C" {
#include <lua/lua.h>
#include <lua/lauxlib.h>
#include <lua/lualib.h>
}
extern lua_State *L = NULL;
bool RunScript(LPCTSTR lpszFileName) {
bool bSuccess = TRUE;
//关闭上次创建的
if (L) {
lua_close(L);
L = NULL;
}
L = luaL_newstate();
if (L) {
luaL_openlibs(L);
luaopen_star(L);
luaopen_mylib2(L);
}
if (lpszFileName != NULL) {
int err = luaL_dofile(L, lpszFileName);
if (err) {
const char *szMsg = lua_tostring(L, -1);
ShowMessage("脚本错误:" + CString(szMsg));
bSuccess = FALSE;
}
}
return bSuccess;
}
string strScript;
DWORD dwSize = 0;
DWORD dwReadWrite = 0;
HANDLE hFile = CreateFile(strLuaFile, GENERIC_READ | GENERIC_WRITE, NULL, NULL, OPEN_EXISTING, NULL, NULL);
if (hFile == INVALID_HANDLE_VALUE) { return; }
dwSize = Star::FileUnit::GetFileSize(hFile, NULL);
if ((int)dwSize > 0) {
PBYTE pBuff = new BYTE[dwSize];
if (pBuff != NULL) {
ReadFile(hFile, pBuff, dwSize, &dwReadWrite, NULL);
strScript.assign((char *)pBuff, dwSize);
delete[]pBuff;
}
}
CloseHandle(hFile);
lua_State* L = luaL_newstate();
if (L) {
luaL_openlibs(L);
//luaopen_mylibs(L);
RunLuaScript(L, strScript);
lua_close(L);
}
bool RunLuaScript(lua_State* L, const string&strScript) {
if (luaL_loadbuffer(L, i->strScript.data(), i->strScript.length(), "") != 0 || lua_pcall(L, 0, LUA_MULTRET, 0)) {
const char* serr = lua_tostring(L, -1);
lua_pop(L, 1);
return false;
}
lua_getglobal(L, "testFunc");
if (lua_pcall(L, 0, 3, 0) != 0) {
serr = lua_tostring(L, -1);
lua_pop(L, 1);
return false;
} else {
if (lua_isnumber(L, -3)) {
nScriptRet1 = lua_tonumber(L, -3);
}
if (lua_isnumber(L, -2)) {
nScriptRet2 = lua_tonumber(L, -2);
}
if (lua_isstring(L, -1)) {
strScriptRet = lua_tostring(L, -1);
}
lua_pop(L, 3);
}
return true;
}
C/C++交互访问Lua脚本
在C代码中访问Lua脚本的变量
- lua_getglobal
在C代码中调用Lua脚本中的函数
- lua_pcall
bool isScriptMatched(lua_State *L, const CString&strAccount, const CString&strParams) {
bool bMatched = false;
if (L == NULL) {
return bMatched;
}
lua_getglobal(L, "onMatch");
if (lua_isfunction(L, -1)) {
lua_pushstring(L, strAccount);
lua_pushstring(L, strParams);
lua_pushstring(L, STRFILEVER);
int err = lua_pcall(L, 3, 1, 0);
if (err) {
const char *szMsg = lua_tostring(L, -1);
ShowMessage(szMsg, MSGSHOWTYPE::ShowAll, MSGBOXTIP::ScriptError);
} else {
int nFit = lua_toboolean(L, -1);
if (nFit != 0) {
bMatched = true;
}
}
}
return bMatched;
}
在C/C++中返回数据给Lua脚本
Lua脚本允许有多个返回值,有多少个返回值就return几,通过lua_pushxxx函数来把返回的数据压到栈上。
- lua_pushinteger
- lua_pushstring
- lua_pushboolean
- lua_pushnumber
lua_pushnumber(L, nRet);
return 1;
文档信息
- 本文作者:zhupite
- 本文链接:https://zhupite.com/lua/lua-in-c.html
- 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)