主要目标
希望能够将 cpp 文件编译成动态库, 以 lua 作为主要运行逻辑(main 函数)
希望解决的问题
- 刚入门 Lua 不太明白,若编译了一个 cpp 文件里包含了一个 Worker 对象,Lua 中如何调用生成这个对象并根据公有函数对私有变量进行操作。
- 查找到的一些示例代码,大多是将 main 逻辑放在 cpp 文件里,生成元表作为全局变量传入 Lua 脚本进行操作。但是将 Lua 作为程序运行入口,C++ 库作为辅助函数,又该如何操作。
- Lua 调试工具各位 Lua 大佬能否介绍一下,或者推荐一些调试方法,lua 的 debug 调试使用我还是有点懵。
自身尝试代码
稍微有点多,感谢耐心观看
classstudy.h
#pragma once
extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
#include <string>
class Worker{
public:
Worker();
~Worker();
int SetName(std::string &name);
int SetAge(int &age);
int SetHight(float &hight);
std::string GetName();
int GetAge();
float GetHight();
private:
std::string name;
int age;
float hight;
};
extern "C" int luaopen_cstudy(lua_State *L);
classstudy.cpp
#include "classstudy.h"
#include <iostream>
/*
Class Worker 的函数定义省略
*/
static int CreateNewWorker(lua_State *L){
//ligth_userdata
// int n = luaL_checkany(L, 1);
Worker **w1 = (Worker**)lua_newuserdata(L, sizeof(Worker*));
*w1 = new Worker();
if(luaL_getmetatable(L, "WorkerClass") == false){
printf("getmetatable nil\n");
}
lua_setmetatable(L, -2);
return 1;
}
static int SetWorkerName(lua_State *L){
luaL_checktype(L, -1, LUA_TSTRING);
std::string var_name = lua_tostring(L, -1);
printf("%s\n", var_name.c_str());
Worker **w1 = (Worker**)lua_newuserdata(L, sizeof(Worker*));
luaL_argcheck(L, w1 != NULL, 1, "invalid user data");
(*w1)->SetName(var_name);
return 0;
}
static int SetWorkerAge(lua_State *L){
luaL_checktype(L, -1, LUA_TNUMBER);
int var_age = lua_tointeger(L, -1);
Worker **w1 = (Worker**)lua_newuserdata(L, sizeof(Worker*));
luaL_argcheck(L, w1 != NULL, 1, "invalid user data");
(*w1)->SetAge(var_age);
return 0;
}
static int SetWorkerHight(lua_State *L){
luaL_checktype(L, -1, LUA_TNUMBER);
float var_hight = lua_tonumber(L, -1);
Worker **w1 = (Worker**)lua_newuserdata(L, sizeof(Worker*));
luaL_argcheck(L, w1 != NULL, 1, "invalid user data");
(*w1)->SetHight(var_hight);
return 0;
}
static int GetWorkerInfo(lua_State *L){
Worker **w1 = (Worker**)lua_newuserdata(L, sizeof(Worker*));
luaL_argcheck(L, w1 != NULL, 1, "invalid user data");
printf("Name: %s\n", ((*w1)->GetName()).c_str());
printf("Age: %d\n", (*w1)->GetAge());
printf("Hight: %f\n", (*w1)->GetHight());
return 0;
}
static int DestoryInfo(lua_State* L)
{
// 释放对象
delete *(Worker**)lua_topointer(L, 1);
return 0;
}
const static luaL_Reg mylib[] = {
// {"NewWorker", CreateNewWorker},
{"SetName", SetWorkerName},
{"SetAge", SetWorkerAge},
{"SetHight", SetWorkerHight},
{"PrintInfo", GetWorkerInfo},
{NULL,NULL}
};
int luaopen_cstudy(lua_State *L){
// C\++对象 = 私有数据 + 类(公共数据 + 公共方法)
// Lua Table = 私有数据 + 元表(元数据 + 元函数)
// luaL_newlib(L, mylib);
lua_pushcfunction(L, CreateNewWorker); // 注册用于创建类的全局函数
lua_setglobal(L, "CWorker");
luaL_newmetatable(L, "WorkerClass");
// 设置自身
lua_pushstring(L, "__gc");
lua_pushcfunction(L, DestoryInfo);
lua_settable(L, -3);
// 设置元表
lua_pushstring(L, "__index"); // 设置元表为自己
lua_pushvalue(L, -2);
lua_settable(L, -3);
lua_pushstring(L, "SetName");
lua_pushcfunction(L, SetWorkerName);
lua_settable(L, -3);
lua_pushstring(L, "SetAge");
lua_pushcfunction(L, SetWorkerAge);
lua_settable(L, -3);
lua_pushstring(L, "SetHight");
lua_pushcfunction(L, SetWorkerHight);
lua_settable(L, -3);
lua_pushstring(L, "PrintInfo");
lua_pushcfunction(L, GetWorkerInfo);
lua_settable(L, -3);
// lua_pop(L, 1);
return 1;
}
classstudy.lua
local csl = require("cstudy")
local Worker = CWorker()
print(debug.getregistry())
Worker.SetName("hello")
Worker.PrintInfo()
-- csl.SetAge(23)
-- csl:SetHight(180.0)
-- csl:PrintInfo()