2012-06-01 28 views
4

我試圖使用一個Lua文件作爲配置或ini。我成功了,但是我的解決方案讓我感到不快。具體而言,get_double,get_intget_string功能需要以可重複使用的方式完成。通用解決方案從lua文件獲取簡單值到C++

我遇到了創建沒有參數的函數模板的問題。 此外,我不知道如何推廣lua_is...lua_to...。我的想法是對我們if(is_same<T,double>::value) return (double)lua_isnumber(L,-1);,但它沒有奏效。

這裏是工作代碼:

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 

它編譯與g++ main.C -I/usr/include/lua5.1/ -llua5.1 ; ./a.out

+0

我覺得應該是維基,但我'm不確定如何進入wiki –

回答

4

這裏是我的代碼使用該目的(更多: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); 
    } 
}; 

- 編輯 - 爲了說明如何使用它,你只需要調用:

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

得到的值:

config = { 
    render = { 
     effects = { 
      blur = false, 
     } 
    } 
} 
+0

在這裏的任何一點之後,你是否必須彈出堆棧? – 2013-10-04 19:42:34