2008년 8월 22일자로 Lua 5.1.4 버젼이 릴리즈 되었습니다. 다운은 루아 공식 사이트에서 받으실 수 있습니다.
컴파일 된 루아 Windows용 버전 또한 LuaForge에서 다운 받으실 수 있습니다. ------------------------------------------------------------------------------------------------------- 헉.. 매주 가면서도 미처 알지 못했네요.....
간만에 rss를 확인하니.. 릴리즈 되었다고 하고. 눈이 헛달린.. ㅜㅡ
이전의 글과 다른 형태로 변경 하였습니다. 각 val_* 인터페이스는 강제적으로 추가 하게 하였고 윈도우 버젼에서는 val 함수를 강제로 뺐습니다. 각 대응함수는 이전의 글에서 설명을 드렸으므로 별도로 설명을 하지 않겠습니다. 소스는 아래의 경로에서 받으실 수 있습니다.
Microsoft Visual C++(이하 MSVC) 2002 버젼 이하에서 LuaRover(이하 LR)가 컴파일이 되지 않는다. MSVC 2002 이하 버젼에는 template 관련 버그가 있고 그것을 유발 할 수 있는 코드가 LR 포함되어 있기 때문이다. 물론 자체 테스트 역시 컴파일은 성공적으로 수행되지는 않았다.
문제가 되는 부분은 아래의 선언에 타입별로 구현된 부분이다.
template<typename T> T val() throw(LuaError);
int의 구현 부분을 예로 들면 아래와 같다.
template<> int LuaObject::val<int> () throw(LuaError) { ... }
구현 부분
성공적으로 컴파일을 하려면 버그를 유발하는 이 template는 코드를 수정하거나 버젼이 높은 버젼을 사용하여 컴파일 하는 방법 외엔 없다.
필자는 전자의 코드 수정 방법을 사용하여 이 버그를 피했다. 수정 내용은 아래와 같다.
template<typename T> T val() throw(LuaError);
->
#ifdef WIN32 int val_int() throw(LuaError); double val_double() throw(LuaError); std::string val_string() throw(LuaError); #else template<typename T> T val() throw(LuaError); #endif
LuaRover.hpp 수정
// 코드 추가 #ifdef WIN32 #define LuaRover_valFunc(type) type LuaObject::val_ ## type () throw(LuaError) #define luaRover_var(type) val_ ## type #else #define LuaRover_valFunc(type) template<> \ type LuaObject::val<type>() throw(LuaError)
#define luaRover_var(type) val<type> #endif
LuaRover.cpp에 추가할 코드
template<> int LuaObject::val<int>() throw(LuaError) { if (!lua_isnumber(lua_state_, -1)) throw LuaError(LuaError::NOT_A_NUMBER, last_key_ + " is Not A Number");
int result = lua_tointeger(lua_state_, -1); pop_stack(); return result; }
->
LuaRover_valFunc(int) { if (!lua_isnumber(lua_state_, -1)) throw LuaError(LuaError::NOT_A_NUMBER, last_key_ + " is Not A Number");
int result = lua_tointeger(lua_state_, -1); pop_stack(); return result; }
위의 코드는 개발에 사용된 루아 코드 입니다 :D 책에도 나와있는 간단한 코드인데 테이블을 탐색할때나 검사 할때 아주 유용하다고 생각 됩니다. :D 우선 글로벌 테이블을 스택에 푸쉬 한 후(lua_getglobal(L,"Window"));) nil 값을 스택에 다시 푸쉬 합니다. 이때 nil을 푸쉬 하는 이유는 이것이 lua_next를 사용해서 처음 탐색한다는 것을 알려 주는 것입니다. stack> table nil 과 같이 스택에 푸쉬가 되어 있을 것입니다 :D 그 후 lua_next를 사용해서 탐색을 시작합니다. lua_next는 스택에서 이전의 키값을 얻어서 다음의 키와 값을 반환하게 됩니다. lua_next가 불리면 스택에 nil 대신에 해쉬 키와 값이이 들어가게 됩니다. 만일 lua 코드 내용이 다음과 같다면
처음의 lua_next함수의 작업이 끝나게 되면 stack> table "Position" table 스택에는 위와 같은 값이 들어가게 됩니다. "Position"은 해쉬 키 이고 다음의 table은 해쉬 값이 됩니다. stackDump는 현 스택을 표시해 주는 부분을 따로 만든것이니 신경 쓰지 않으셔도 됩니다. 바로 밑의 printf도 마찬가지고요 :D lua_pop은 마지막의 table을 지우게 하는것인데 만일 지우지 않고 수행할 경우 lua_next는 더이상 실행 되지 않습니다. 그러니 마지막의 해쉬값은 반드시 스택에서 pop하셔야 합니다.
종종 햇갈리는 것중의 하나는 스택의 순서인데 lua_next는 스택의 바닥에서 부터 lua_pop은 최상단에서 부터라고 알아 두시면 좋을 듯 합니다. 사족을 붙이면 lua_pop은 lua_settop의 매크로 입니다. :D