General solution for getting simple values ​​from a lua file in C ++

I am trying to use a Lua file as a configuration or ini. I succeeded, but my decision annoys me. In particular, the get_double , get_int and get_string must be executed in a reusable way.

I am having trouble creating function templates that have no arguments. Also, I'm not sure how to generalize lua_is... and lua_to... My idea was for us if(is_same<T,double>::value) return (double)lua_isnumber(L,-1); but that didn't work.

Here is the working code:

main.cc:

 #include <iostream> #include <lua.hpp> using namespace std; class Lua_vm { private: lua_State *L; public: double get_double(const char *var_name) { lua_getglobal(L,var_name); if (!lua_isnumber(L,-1)) { cout << "error: " << var_name << " is of a wrong type\n"; } return (double)lua_tonumber(L,-1); lua_pop(L,1); } int get_int(const char *var_name) { lua_getglobal(L,var_name); if (!lua_isnumber(L,-1)) { cout << "error: " << var_name << " is of a wrong type\n"; } return (int)lua_tonumber(L,-1); lua_pop(L,1); } string get_string(const char *var_name) { lua_getglobal(L,var_name); if (!lua_isstring(L,-1)) { cout << "error: " << var_name << " is of a wrong type\n"; } return string(lua_tostring(L,-1)); lua_pop(L,1); } Lua_vm(const char *lua_config_filename) { L = lua_open(); if (luaL_loadfile(L, lua_config_filename) || lua_pcall(L, 0,0,0)) { cout << "error: " << lua_tostring(L,-1) << "\n"; } lua_pushnil(L); } ~Lua_vm() { lua_close(L); } }; int main(int argc, char** argv) { Lua_vm lvm("config.lua"); cout << "vol is " << lvm.get_double("vol") << "\n"; cout << "rho is " << lvm.get_int("rho") << "\n"; cout << "method is " << lvm.get_string("method") << "\n"; return 0; } 

config.lua:

 method = "cube" len = 3.21 rho = 13 vol = len*len*len mass = vol*rho 

It compiles with g++ main.C -I/usr/include/lua5.1/ -llua5.1 ; ./a.out g++ main.C -I/usr/include/lua5.1/ -llua5.1 ; ./a.out

+4
source share
1 answer

Here is the code I use for this purpose (more details: http://tom.rethaller.net/wiki/projects/prologue/lua )

 class LuaState { private: lua_State *L; // [...] public: // get function template<typename T> T get(const char * varname) { char temp[64]; memset(temp, 0, sizeof(temp)); int i=0; int j=0; int n=0; while (varname[i] != '\0') { char c = varname[i]; if (c == '.') { if (n == 0) lua_getglobal(L, temp); else lua_getfield(L, -1, temp); ++n; memset(temp, 0, sizeof(temp)); j = 0; if (lua_isnil(L, -1)) return 0; } else { temp[j] = c; ++j; } ++i; } if (n == 0) lua_getglobal(L, temp); else lua_getfield(L, -1, temp); return lua_get<T>(); } // Generic get template<typename T> T lua_get() { return 0; } // Specializations template <> float lua_get<float>() { return lua_tonumber(L, -1); } template <> double lua_get<double>() { return lua_tonumber(L, -1); } template <> bool lua_get<bool>() { return lua_toboolean(L, -1); } template <> int lua_get<int>() { return lua_tointeger(L, -1); } template <> unsigned int lua_get<unsigned int>() { return (unsigned int)lua_tonumber(L, -1); } template <> const char * lua_get<const char *>() { return lua_tostring(L, -1); } }; 

- Edit - To illustrate how to use it, you just need to call:

 bool use_blur = lua_state.get<bool>("config.render.effects.blur"); 

to get the value:

 config = { render = { effects = { blur = false, } } } 
+4
source

Source: https://habr.com/ru/post/1415515/


All Articles