E D R S I H C RSS
ID
Password
Join
ì§‘ì„ ì‚¬ì§€ ë§ê³  ì´ì›ƒì„ 사ë¼. ―유럽 ì†ë‹´

 * 5.0ì—서는 테그 메소드가 없어지고 메타테ì´ë¸”ì´ë¼ëŠ” ê°œë…ì„ ë‘는 등, 왠만한 모든 제어를 í…Œì´ë¸” 위주로 만들어버렸습니다. 어쨌든 공부삼아 다시 번역해봅니다.
  • íìŒ, ì´ì „ê³¼ì˜ í˜¸í™˜ì„ ìœ„í•´ lua_getglobal() 함수 ê°™ì€ ê²ƒë“¤ì´ ëª¨ë‘ ë§¤í¬ë¡œë¡œ 만들어져 있군요. ì´ ë§¤í¬ë¡œë¥¼ 사용해서 C 소스ìƒì—서 루아 함수를 호출하는 예는 ì›ë³¸ì—는 없지만 제가 한번 추가해보았습니다. "Cì—서 루아 함수를 호출하기"를 참고하세요.
  • 메뉴얼 ì „ì²´ê°€ 아닌 중간 4장만 번역한 것입니다. (어디어디 참조)ë¼ê³  ì ì€ ë¶€ë¶„ì€ ì „ì²´ 메뉴얼ì—ì„œì˜ ì´ì•¼ê¸°ìž…니다.
  • ì§ì ‘ 소스를 컴파ì¼í•´ì„œ ì •ì  lib로 만들어쓰는 ê²ƒì´ íŽ¸í•˜ë‹¤ëŠ” ê²ƒì„ ìš”ì¦˜ ëŠë¼ê³  있습니다. êµ³ì´ ë°°í¬ë³¸ ì˜ì‹í•  필요없ë”êµ°ìš”.
  • 루아 5.0 알파 소스 : [http]http://www.lua.org/ftp/lua-5.0-alpha.tar.gz
  • ì¼ë¶€ë¥¼ 번역해서 ë‚´ìš©ì„ ì´ë©”ì¼ë¡œ 보내주신 M안성규님께 ê°ì‚¬ë¥¼ 드립니다.

Contents

1 개요
2 State
3 쓰레드
4 Stackê³¼ ì¸ë±ìФ
5 ìŠ¤íƒ ê´€ë¦¬
6 스íƒì— 질ì˜í•˜ê¸°
7 스íƒìœ¼ë¡œë¶€í„° ê°’ì„ ì–»ì–´ë‚´ê¸°
8 스íƒìœ¼ë¡œ ê°’ì„ push 하기
9 개비지 ì»¬ëž™ì…˜ì„ ì¡°ì ˆí•˜ê¸°
10 유저ë°ì´íƒ€ 루아 타입
11 메타테ì´ë¸”
12 루아 ì²­í¬ë¥¼ 로딩하기
13 í…Œì´ë¸” 관리
14 ì „ì—­ 변수 í…Œì´ë¸”ì„ ê´€ë¦¬í•˜ê¸°
15 í…Œì´ë¸”ì€ ë°°ì—´ë¡œì¨ ì‚¬ìš©í•˜ê¸°
16 Cì—서 루아 함수를 호출하기
17 Protected Calls
18 C 함수를 ë£¨ì•„ì— ë“±ë¡í•˜ê¸°
19 Defining C Closures
19.1 Registry

1 개요 #

ì´ ì„¹ì…˜ì€ ë£¨ì•„ì˜ API(다시ë§í•˜ë©´, 호스트 프로그램ì—서 루아와 통신하기 위한 ìš©ë„로 ì œìž‘ëœ C í•¨ìˆ˜ë“¤ì˜ ëª¨ìŒ)ì— ëŒ€í•´ì„œ 설명하고 있다. 모든 API 함수와 ê´€ë ¨ëœ íƒ€ìž… ë° ìƒìˆ˜ì •ì˜ë“¤ì€ lua.h í—¤ë”í™”ì¼ì— ì •ì˜ë˜ì–´ìžˆë‹¤.

우리가 "함수"ë¼ëŠ” 용어를 사용하ë”ë¼ë„, APIë‚´ì˜ ëª‡ëª‡ êµ¬í˜„ì€ ë§¤í¬ë¡œë¡œ ì œê³µë  ìˆ˜ë„ ìžˆë‹¤. ì´ëŸ¬í•œ ë©”í¬ë¡œë“¤ì€ ê° ì¸ìžë“¤ì„ 실제로 한번씩만 사용하며(첫번째ì¸ìžëŠ” 예외ì´ë‹¤. 왜ëƒë©´ 루아 stateì´ë¯€ë¡œ ì´ê²ƒì€ 여러번 ì‚¬ìš©ë  ìˆ˜ 있다.), ë”°ë¼ì„œ 숨겨진 부수ì ì¸ 효과를 ì¼ìœ¼í‚¤ì§€ 않는다.

2 State #

루아 ë¼ì´ë¸ŒëŸ¬ë¦¬ëŠ” 언제나 ìž¬ì§„ìž…ì´ ê°€ëŠ¥í•˜ë‹¤ : ì´ê²ƒì€ ë¼ì´ë¸ŒëŸ¬ë¦¬ê°€ ì „ì—­ë³€ìˆ˜ë“¤ì„ ê°€ì§€ê³  있지 않다는 ê²ƒì„ ì˜ë¯¸í•œë‹¤. 루아 ì¸í„°í”„ë¦¬í„°ì˜ ì „ì²´ 설정 ìƒíƒœ(ì „ì—­ 변수들, 스íƒë“±ë“±)ì€ lua_Stateë¼ê³  하는 ë™ì ìœ¼ë¡œ í• ë‹¹ëœ êµ¬ì¡°ì²´ì— ë‹´ê²¨ì§„ë‹¤. ì´ state는 루아 ë¼ì´ë¸ŒëŸ¬ë¦¬ì˜ 모든 í•¨ìˆ˜ì˜ ì²«ì§¸ ì¸ìžë¡œ 넘겨지게 ëœë‹¤. (lua_open() 함수는 제외)

루아 ë¼ì´ë¸ŒëŸ¬ë¦¬ë¥¼ 사용하기 가장 처ìŒì— 반드시 state를 ìƒì„±í•´ì•¼í•˜ëŠ”ë°, ë‹¤ìŒ í•¨ìˆ˜ë¥¼ 호출하여 수행할 수 있다.
lua_State *lua_open (void);

충분히 루아를 사용하고 ì´ì œ ìƒì„±í•œ state를 해제할 때ì—는 ë‹¤ìŒ í•¨ìˆ˜ë¥¼ 사용한다.
void lua_close (lua_State *L);

ì´ í•¨ìˆ˜ëŠ” 주어진 루아 state í™˜ê²½ë‚´ì˜ ëª¨ë“  ê°ì²´ë¥¼ 소멸시킨다. (ì•Œë§žì€ ê°œë¹„ì§€ 컬랙션 ë©”íƒ€ë©”ì†Œë“œë“¤ì„ í˜¸ì¶œí•¨ìœ¼ë¡œì¨ ì´ê²ƒì„ 수행한다.) 그리고 state를 ì‚¬ìš©í•˜ëŠ”ë° í• ë‹¹ëœ ëª¨ë“  ë™ì  메모리를 해제한다. ì¼ë°˜ì ìœ¼ë¡œ, ì´ í•¨ìˆ˜ëŠ” 호출할 필요가 없다. 왜ëƒí•˜ë©´, 모든 리소스는 ì›ëž˜ì˜ 호스트 í”„ë¡œê·¸ëž¨ì´ ì¢…ë£Œí•  때 반환ë˜ê³  í•´ì œë˜ëŠ” ê²ƒì¸ ì›ì¹™ì´ë¯€ë¡œ 프로그램 종료가 확실하다면 ì´ í•¨ìˆ˜ëŠ” 사용하지 ì•Šì•„ë„ ëœë‹¤. 하지만, 오랫ë™ì•ˆ 실행ë˜ëŠ” 프로그램(웹서버와 ê°™ì€ ë°ëª¬í”„로그램과 ê°™ì€)ì€ ë©”ëª¨ë¦¬ë¥¼ ì•„ë¼ê¸° 위해서ë¼ë“ ê°€ 여러가지 ì´ìœ ë¡œ ì¤‘ê°„ì— state를 해제할 ìˆ˜ë„ ìžˆì„ ê²ƒì´ë‹¤. lua_open() 함수를 제외하고 루아 APIì˜ ëª¨ë“  함수는 첫번째 ì¸ìžë¡œ state를 요구한다.

3 쓰레드 #

루아는 다중 쓰레드 ì‹¤í–‰ì— ëŒ€í•œ 부분ì ì¸ ì§€ì›ì„ 제공한다. 만약 ë©€í‹°ì“°ë ˆë”©ì„ ì§€ì›í•˜ëŠ” C ë¼ì´ë¸ŒëŸ¬ë¦¬ë¥¼ 가지고 있다면, 루아는 ë£¨ì•„ë‚´ë¶€ì˜ ë™ë“±í•œ 설비를 구현하기 위해 ê·¸ ë¼ì´ë¸ŒëŸ¬ë¦¬ì™€ 협력할 수 있다. (If you have a C library that offers multi-threading, then Lua can cooperate with it to implement the equivalent facility in Lua.) ë˜í•œ 루아는 ì“°ë ˆë“œì˜ ìƒìœ„ì—서 ìžê¸°ìžì‹ ì˜ ë³´ì¡°ë£¨í‹´ì„ êµ¬í˜„í•œë‹¤. ë‹¤ìŒ í•¨ìˆ˜ëŠ” ë£¨ì•„ë‚´ì— ìƒˆë¡œìš´ 쓰레드를 ìƒì„±í•œë‹¤.
lua_State *lua_newthread (lua_State *L);

ì´ í•¨ìˆ˜ëŠ” 새로운 stateê°€ 반환한다. ì´ state는 모든 ì „ì—­ 환경(í…Œì´ë¸”등등)ì€ ê³µìœ í•˜ì§€ë§Œ ë…립ì ì¸ 실시간 스íƒì„ 가지고 있다. (ì´ì™€ ê°™ì€ ë‹¤ì¤‘ 스íƒì˜ ì‚¬ìš©ì€ ë°˜ë“œì‹œ C와 함께 "ë™ê¸°í™” ë˜ì–´ì•¼ 한다". How to explain that? TO BE WRITTEN.) ê° ì“°ë ˆë“œëŠ” 전역변수를 위한 ë…립ì ì¸ í…Œì´ë¸”ì„ ê°€ì§€ê³  있다. 쓰레드를 ìƒì„±í•˜ë©´, ì´ í…Œì´ë¸”ì€ ì¸ìžë¡œ 주어진 state와 ë™ì¼í•˜ë‹¤. 그러나 ìƒì„±ëœ ì´í›„ì—는 ê·¸ ë‚´ìš©ì€ ë…립ì ìœ¼ë¡œ 변할 수 있다. (역주 : 호스트ì—서 멀티쓰레드 프로그래ë°ì„ 할때 별ë„ì˜ ì“°ë ˆë“œë¥¼ ìƒì„±í•˜ê³ , 쓰레드가 소멸ë˜ë©´ 차후 병합하는 ê¸°ëŠ¥ì„ í•˜ëŠ” 것으로 추측ë¨. ì•„ì§ì€ 불안한 ëŠë‚Œì´...-_-;)

ìƒì„±í•œ 쓰레드는 ë‹¤ìŒ í•¨ìˆ˜ë¡œ 없앨 수 있다.
void lua_closethread (lua_State *L, lua_State *thread);

맨 ë§ˆì§€ë§‰ì˜ stateì— ëŒ€í•œ 쓰레드는 ì´ í•¨ìˆ˜ë¡œ 닫으면 안ëœë‹¤. 대신ì—, 마지막 쓰레드 state는 lua_close()를 사용하여 해제하ë¼.

4 Stackê³¼ ì¸ë±ìФ #

루아는 C 함수로부터 ê°’ë“¤ì„ ë„˜ê²¨ë°›ê¸° 위해 ê°€ìƒì˜ 스íƒì„ 사용한다. ì´ ìŠ¤íƒì•ˆì˜ ê°ê°ì˜ 요소는 루아 값으로 표현ëœë‹¤.(nil, number, string, 등등)

ê°ê°ì˜ C í•¨ìˆ˜ì˜ ì‹¤í–‰ì€ (ê°€ìƒì ìœ¼ë¡œ) ê°ìžì˜ 스íƒì„ 가지고 있다. 루아가 C 함수를 호출할때마다, í˜¸ì¶œëœ í•¨ìˆ˜ëŠ” 새로운 스íƒì„ 얻게 ëœë‹¤.(ì´ ìŠ¤íƒì€ ì´ì „ì˜ ìŠ¤íƒ í˜¹ì€ í™œì„±í™” ìƒíƒœì¸ C í•¨ìˆ˜ë“¤ì˜ ìŠ¤íƒë“¤ì™€ëŠ” ë…립ì ì´ë‹¤)

편ì˜ìƒ, APIë‚´ì˜ ëŒ€ë¶€ë¶„ì˜ ì§ˆì˜ í˜•ì‹ì˜ ëª…ë ¹ë“¤ì€ ì—„ê²©í•œ ìŠ¤íƒ ì›ì¹™ì„ 따르지 않는다. 대신ì—, ì´ë“¤ì€ ì¸ë±ìŠ¤ë¥¼ 사용하는 ê²ƒì— ì˜í•´ 스íƒì˜ ê° ìš”ì†Œë¥¼ 참조하는 ê²ƒì´ ê°€ëŠ¥í•˜ë‹¤. ì–‘ìˆ˜ê°’ì˜ ì¸ë±ìŠ¤ëŠ” 스íƒìƒì˜ 절대 위치를 ì˜ë¯¸í•œë‹¤. (1부터 시작한다) ìŒìˆ˜ê°’ì˜ ì¸ë±ìŠ¤ëŠ” 스íƒì˜ topì—ì„œë¶€í„°ì˜ offsetì„ ë‚˜íƒ€ë‚¸ë‹¤. ì¢€ë” ëª…í™•í•˜ê²Œ ë§í•˜ìžë©´, 만약 스íƒì´ nê°œì˜ ìš”ì†Œë¥¼ 가지고 있다면, ì¸ë±ìФ 1ì€ ê°€ìž¥ ì²˜ìŒ ìš”ì†Œë¥¼ 나타낸다.(다시 ë§í•˜ë©´, 스íƒì— ë§¨ì²˜ìŒ í‘¸ì‰¬ëœ ìš”ì†Œë¥¼ ì˜ë¯¸í•œë‹¤) 그리고 ì¸ë±ìФ nì€ ê°€ìž¥ 마지막 요소를 ì˜ë¯¸í•œë‹¤. -1 ì¸ë±ìŠ¤ëŠ” 가장 마지막 ì¸ë±ìŠ¤ë¥¼ 나타낸다. (다시ë§í•˜ìžë©´, top ìœ„ì¹˜ì˜ ìš”ì†Œë¥¼ 가리틴다.) 그리고 -n ì¸ë±ìŠ¤ëŠ” 첫번째 ì¸ë±ìŠ¤ë¥¼ 나타낸다. ë‚´ë¶€ì ìœ¼ë¡œ ì¸ë±ìŠ¤ê°€ ì ë²•한지를 검사하는 ì¡°ê±´ì€ ì¸ë±ìФ ê°’ì´ 1ê³¼ 스íƒì˜ top사ì´ì— 놓여있는지 여부ì´ë‹¤. (다시ë§í•˜ë©´, 1 <= abs(ì¸ë±ìФ) <= top)

코드ìƒì˜ 언제ë¼ë„, ë‹¤ìŒ í•¨ìˆ˜ë¥¼ 호출하여 top ìš”ì†Œì˜ ì¸ë±ìŠ¤ë¥¼ ì–»ì„ ìˆ˜ 있다.
int lua_gettop (lua_State *L);

ì¸ë±ìŠ¤ê°€ 1부터 시작하기 때문ì—, lua_gettop() í•¨ìˆ˜ì˜ ë°˜í™˜ê°’ì€ ìŠ¤íƒì•ˆì— í‘¸ì‰¬ëœ ìš”ì†Œì˜ ìˆ˜ì™€ 같다. (그러므로 0ì´ ë°˜í™˜ë˜ì—ˆë‹¤ë©´ 스íƒì´ 비었다는 ëœ»ì´ ëœë‹¤.) 루아 API를 ì‚¬ìš©í•˜ëŠ”ë° ìžˆì–´ì„œ, ì—¬ëŸ¬ë¶„ì€ ìŠ¤íƒ ì˜¤ë²„í”Œë¡œìš°ë¥¼ 검사할 ì±…ìž„ì´ ìžˆë‹¤. ë‹¤ìŒ í•¨ìˆ˜ë¥¼ 사용하여 검사한다.
int lua_checkstack (lua_State *L, int extra);

ì´ í•¨ìˆ˜ë¥¼ 실행하면 스íƒí¬ê¸°ê°€ top + extraê°’ë§Œí¼ ì¦ê°€í•˜ê²Œ ëœë‹¤. 만약 지정한 extraë§Œí¼ ì¦ê°€í•˜ì§€ 못한다면 false를 반환한다. ì´ í•¨ìˆ˜ëŠ” 절대로 스íƒê³µê°„ì„ ì¤„ì–´ë“¤ê²Œ 하지 않는다. 만약 스íƒì´ ì´ë¯¸ 새로운 í¬ê¸°ë³´ë‹¤ í¬ë‹¤ë©´, 변경ë˜ì§€ ì•Šì€ ì±„ë¡œ 유지ëœë‹¤.

루아가 C 함수를 호출할 때는 언제ë¼ë„, lua_checkstack(L, LUA_MINSTACK)ì˜ ê²°ê³¼ê°€ trueì¸ ê²ƒì„ ë³´ìž¥í•œë‹¤. 다시ë§í•˜ë©´, ì ì–´ë„ LUA_MINSTACK 위치가 ì•„ì§ ì‚¬ìš©ê°€ëŠ¥í•˜ë‹¤ëŠ” 뜻ì´ë‹¤. LUA_MINSTACKì€ lua.hì— 20으로 ì •ì˜ë˜ì–´ 있으며, 실제 코드ì—서 ë°˜ë³µë¬¸ì„ ì‚¬ìš©í•˜ì—¬ 스íƒì— ê°’ì„ í‘¸ì‰¬í•˜ì§€ 않는다면 ìŠ¤íƒ í¬ê¸°ì— 대해서는 ì¼ë°˜ì ìœ¼ë¡œ 걱정할 필요가 없다.

ëŒ€ë¶€ë¶„ì˜ ì§ˆì˜ í•¨ìˆ˜ë“¤ì€ í—ˆìš©ëœ ìŠ¤íƒ ê³µê°„ë‚´ì˜ ê°’ë§Œ ì¸ë±ìŠ¤ë¡œì¨ ë°›ì•„ë“¤ì¸ë‹¤. 다시ë§í•˜ë©´, 최대 ìŠ¤íƒ í¬ê¸°ë¥¼ 초과하는 ì¸ë±ìŠ¤ë“¤ì€ lua_checkstack() 함수를 사용하여 설정해야한다. ì´ì™€ ê°™ì€ ì¸ë±ìŠ¤ë“¤ì€ "허용가능한 ì¸ë±ìФ"ë¼ê³  부르기로 한다. ì¢€ë” ì •í˜•ì ìœ¼ë¡œ ë§í•œë‹¤ë©´, 우리는 "허용가능한 ì¸ë±ìФ"를 다ìŒê³¼ ê°™ì´ ì •ì˜í•  수 있다.
(index < 0 && abs(ì¸ë±ìФ) <= top) || (ì¸ë±ìФ > 0 && ì¸ë±ìФ <= top + stackspace)

0 ì¸ë±ìŠ¤ëŠ” 절대로 ì ‘ê·¼ì´ ë¶ˆê°€ëŠ¥í•œ ì¸ë±ìФë¼ëŠ” ì ì— 주ì˜í•˜ë¼. Unless otherwise noticed, any function that accepts valid indices can also be called with pseudo-indices, which represent some Lua values that are accessible to the C code but are not in the stack. 가짜 ì¸ë±ìŠ¤ëŠ” 전역변수테ì´ë¸”(4.13장 참조), 래지스트리, C í•¨ìˆ˜ì˜ upvalueë“¤ì„ ì–µì„¸ìŠ¤í•˜ëŠ”ë° ì‚¬ìš©ëœë‹¤.

5 ìŠ¤íƒ ê´€ë¦¬ #

루아 API는 기본ì ì¸ 스íƒê´€ë¦¬ë¥¼ 위해 ë‹¤ìŒ í•¨ìˆ˜ë“¤ì„ ì œê³µí•œë‹¤.
void lua_settop    (lua_State *L, int index);
void lua_pushvalue (lua_State *L, int index);
void lua_remove    (lua_State *L, int index);
void lua_insert    (lua_State *L, int index);
void lua_replace   (lua_State *L, int index);

lua_settop()ì€ 0 ë˜ëŠ” 사용가능한 ì¸ë±ìŠ¤ë¥¼ 받아서 스íƒì˜ top으로 설정한다. 만약 새로운 topì´ ì§€ì •í•˜ê¸° 전보다 í¬ë‹¤ë©´, 늘어난 ë§Œí¼ì˜ 스íƒê³µê°„ì€ nil로 채워지게 ëœë‹¤. 만약 ì¸ë±ìŠ¤ê°€ 0ì´ë©´ 모든 ìŠ¤íƒ ìš”ì†ŒëŠ” 제거ëœë‹¤. lua.hì— ë‹¤ìŒê³¼ ê°™ì€ ì“¸ë§Œí•œ 매í¬ë¡œê°€ ì •ì˜ë˜ì–´ìžˆë‹¤. ì´ê²ƒì€ nê°œë§Œí¼ ìŠ¤íƒìœ¼ë¡œë¶€í„° pop처리를 수행한다.

#define lua_pop(L,n) lua_settop(L, -(n)-1)

lua_pushvalue() 함수는 주어진 ì¸ë±ìФìƒì˜ ê°’ì˜ ë³µì‚¬ë³¸ì„ ìŠ¤íƒì— 푸쉬 처리한다. lua_remove()는 지정한 ì¸ë±ìФ ìœ„ì¹˜ì˜ ê°’ì„ ì œê±°í•˜ê³ , 지워진 ê³³ì„ ë§¤ê¾¸ê¸°ìœ„í•´ 나머지 ìœ„ì¹˜ì˜ ìš”ì†Œë“¤ì„ ëª¨ë‘ ëŒì–´ì˜¬ë¦°ë‹¤. (다시ë§í•˜ë©´, 주어진 ìœ„ì¹˜ì˜ ê°’ë§Œ 빼낸다.) lua_replace()는 ê° ìš”ì†Œë“¤ì˜ ìœ„ì¹˜ì´ë™ì—†ì´ 주어진 ì¸ë±ìФ 위치로 top ìš”ì†Œì˜ ê°’ì„ ì´ë™ì‹œí‚¨ë‹¤. (ì´ê²ƒì€ topì˜ ê°’ì„ ì£¼ì–´ì§„ 위치로 ë®ì–´ì“°ê³ , pop처리한 것과 같다.) ì´ í•¨ìˆ˜ë“¤ì€ ë°˜ë“œì‹œ ì ë²•한 ì¸ë±ìŠ¤ë§Œì„ ë°›ì•„ë“¤ì¸ë‹¤. (확실하게 하ìžë©´, 가짜 ì¸ë±ìŠ¤ë¥¼ 가지고 lua_remove나 lua_insert를 호출할 수 없다. 가짜ì¸ë±ìŠ¤ëŠ” 실제 스íƒìƒì˜ 위치를 나타내지 않기 때문ì´ë‹¤.)

아래 예ì—서는 10 20 30 40 50*ê³¼ ê°™ì´ ìŠ¤íƒì´ 있다고 가정하고 í•¨ìˆ˜ë“¤ì„ ì ìš©í•œ 것ì´ë‹¤. (바닥ì—서 top까지 순서대로 나열한 것ì´ë©° * 표시가 topì„ ì˜ë¯¸í•œë‹¤)

lua_pushvalue(L, 3)    --> 10 20 30 40 50 30*
lua_pushvalue(L, -1)   --> 10 20 30 40 50 30 30*
lua_remove(L, -3)      --> 10 20 30 40 30 30*
lua_remove(L,  6)      --> 10 20 30 40 30*
lua_insert(L,  1)      --> 30 10 20 30 40*
lua_insert(L, -1)      --> 30 10 20 30 40*  (no effect)
lua_replace(L, 2)      --> 30 40 20 30*
lua_settop(L, -3)      --> 30 40 20*
lua_settop(L,  6)      --> 30 40 20 nil nil nil*

6 스íƒì— 질ì˜í•˜ê¸° #

ìŠ¤íƒ ìš”ì†Œê°’ì˜ íƒ€ìž…ì„ ê²€ì‚¬í•˜ê¸° 위해서 다ìŒê³¼ ê°™ì€ í•¨ìˆ˜ë“¤ì´ ì œê³µëœë‹¤.
int         lua_type        (lua_State *L, int index);
int         lua_isnil       (lua_State *L, int index);
int         lua_isboolean   (lua_State *L, int index);
int         lua_isnumber    (lua_State *L, int index);
int         lua_isstring    (lua_State *L, int index);
int         lua_istable     (lua_State *L, int index);
int         lua_isfunction  (lua_State *L, int index);
int         lua_iscfunction (lua_State *L, int index);
int         lua_isuserdata  (lua_State *L, int index);
int         lua_isdataval   (lua_State *L, int index);

ì´ í•¨ìˆ˜ë“¤ì€ ì‚¬ìš©ê°€ëŠ¥í•œ ì¸ë±ìŠ¤ë¥¼ 사용하여 í˜¸ì¶œë  ìˆ˜ 있다. lua_type() 함수는 해당 ì¸ë±ìФìƒì˜ ê°’ì˜ íƒ€ìž…ì„ ë°˜í™˜í•œë‹¤. LUA_TNONEì€ ì ë²•하지 ì•Šì€ ì¸ë±ìФë¼ëŠ” ì˜ë¯¸ì´ë©°(다시ë§í•˜ë©´, 스íƒì˜ ìƒíƒœê°€ 비어있는 ìƒíƒœì¼ ê²½ìš°ë„ ë“¤ 수 있다.) lua.hì— ë‹¤ìŒê³¼ ê°™ì´ íƒ€ìž…ì— ë”°ë¥¸ ìƒìˆ˜ë“¤ì´ ì •ì˜ë˜ì–´ìžˆë‹¤ : LUA_TNIL, LUA_TNUMBER, LUA_TBOOLEAN, LUA_TSTRING, LUA_TTABLE, LUA_TFUNCTION, LUA_TUSERDATA, LUA_TLIGHTUSERDATA. ë‹¤ìŒ í•¨ìˆ˜ëŠ” ê° ìƒìˆ˜ë¥¼ íƒ€ìž…ëª…ì„ ë‚˜íƒ€ë‚´ëŠ” 문ìžì—´ë¡œ 번역해준다.
const char *lua_typename  (lua_State *L, int type);

lua_is...으로 시작하는 í•¨ìˆ˜ë“¤ì€ ë§Œì•½ 주어진 타입과 호환ëœë‹¤ë©´ 1ì„ ë°˜í™˜í•˜ë©°, 아니면 0ì„ ë°˜í™˜í•œë‹¤. lua_isboolean() 함수는 ì´ ì›ì¹™ì—서 예외ì´ë‹¤. ì´ í•¨ìˆ˜ëŠ” 단지 boolean ê°’ì—ë§Œ 사용ëœë‹¤. (그렇지 않으면 ì´ í•¨ìˆ˜ëŠ” 쓸모가 ì—†ì„ì§€ë„ ëª¨ë¥¸ë‹¤. booleanê³¼ 호환ë˜ëŠ” ê°’ì€ ì—†ë‹¤.) ì ë²•하지 ì•Šì€ ì¸ë±ìŠ¤ë¥¼ 사용하면 언제나 ì´ í•¨ìˆ˜ë“¤ì€ 0ì„ ë°˜í™˜í•œë‹¤. lua_isnumber() 함수는 숫ìžë‚˜ 숫ìžë¡œë§Œ ì´ë£¨ì–´ì§„ 문ìžì—´ì„ 받아들ì´ë©°, lua_isstring()ì€ ë¬¸ìžì—´ê³¼ 숫ìžë“¤ì„ 받아들ì¸ë‹¤. lua_isfunction()ì€ ë£¨ì•„ 함수와 C 함수 ì–‘ìª½ì„ ë°›ì•„ë“¤ì¸ë‹¤. 루아 함수ì¸ì§€ C 함수ì¸ì§€ë¥¼ 구별하려면 lua_iscfunction() 를 사용하ë¼. 숫ìžì¸ì§€ 숫ìžë¡œ ì´ë£¨ì–´ì§„ 문ìžì—´ì¸ì§€ë¥¼ 구별하려면 lua_type() 함수를 사용하면 ëœë‹¤.

API는 ë˜í•œ 스íƒìƒì˜ ë‘ ê°’ë“¤ì„ ë¹„êµí•˜ê¸° 위한 í•¨ìˆ˜ë“¤ì„ ê°€ì§€ê³  있다.
int lua_equal    (lua_State *L, int index1, int index2);
int lua_lessthan (lua_State *L, int index1, int index2);

'.. 와 다르다'ë¼ë˜ê°€ '..보다 í¬ë‹¤' 비êµëŠ” 위 í•¨ìˆ˜ì˜ ìˆœì„œë§Œ 바꾸어 충분히 í•  수 있다. ê° í•¨ìˆ˜ë“¤ì€ ë§Œì•½ ì ë²•하지 ì•Šì€ ì¸ë±ìŠ¤ë¥¼ 사용했다면 0ì„ ë°˜í™˜í•œë‹¤.

7 스íƒìœ¼ë¡œë¶€í„° ê°’ì„ ì–»ì–´ë‚´ê¸° #

스íƒì— 있는 ê°’ì€ ëª…ì‹œëœ C형태로 전송하기 위해서, ì—¬ëŸ¬ë¶„ì€ ì•„ëž˜ì˜ í•¨ìˆ˜ë“¤ì„ ì‚¬ìš©í•  수 있다:
int            lua_toboolean   (lua_State *L, int index);
lua_Number     lua_tonumber    (lua_State *L, int index);
const char    *lua_tostring    (lua_State *L, int index);
size_t         lua_strlen      (lua_State *L, int index);
lua_CFunction  lua_tocfunction (lua_State *L, int index);
void          *lua_touserdata  (lua_State *L, int index);

ì´ í•¨ìˆ˜ë“¤ì€ ì–´ë–¤ ë°›ì•„ë“¤ì¼ ìˆ˜ 있는 ì¸ë±ìФ ê°’ê³¼ 함께 í˜¸ì¶œë  ìˆ˜ 있다. 만약 ì ì ˆí•œ ì¸ë±ìФ ê°’ì´ ì£¼ì–´ì§€ì§€ 않으면 주어진 ê°’ì´ ë¶€ì •í™•í•œ íƒ€ìž…ì„ ê°€ì§„ 것으로 ë™ìž‘한다.

lua_toboolean() 함수는 주어진 ì¸ë±ìŠ¤ì— ìžˆëŠ” 루아 ê°’ì„ C불리언(0ë˜ëŠ”,1) 값으로 바꾼다. 모든 ë£¨ì•„ì˜ í…ŒìŠ¤íŠ¸ì™€ ê°™ì´ ì–´ë–¤ ë£¨ì•„ê°’ì— ëŒ€í•˜ì—¬ 1ì„ ë¦¬í„´í•˜ê³  ì ì ˆí•œ ì¸ë±ìФ ê°’ì´ ì£¼ì–´ì§€ì§€ ì•Šì€ ê²½ìš°ì—는 0ì„ ë¦¬í„´í•œë‹¤. (만약 ì—¬ëŸ¬ë¶„ì´ ì™„ì „í•œ 불리언 ê°’ì„ ë°›ê³  싶다면 lua_isboolean함수를 ì´ìš©í•˜ì—¬ í˜•ì„ ì±„í¬í•´ ë³¼ 수 있다.)

lua_tonumber()함수는 주어진 ì¸ë±ìŠ¤ì˜ ê°’ì€ ìˆ«ìžë¡œ 바꿔준다(lua_Numberì˜ ê¸°ë³¸ê°’ì€ doubleì´ë‹¤). 루아 변수는 숫ìžì´ê±°ë‚˜ 변환가능한 숫ìžë¡œ ë˜ì–´ 있는 문ìžì—´ì´ë‹¤. (2.4ì ˆì„ ë³´ê¸° 바란다.) ê¸°íƒ€ì˜ ê²½ìš°ëŠ” 0ì„ ë¦¬í„´í•œë‹¤.

lua_tostring() 함수는 주어진 ì¸ë±ìŠ¤ì˜ ê°’ì„ ë¬¸ìžì—´(const char*)로 변환해준다. 루아 변수는 문ìžì—´ì´ê±°ë‚˜ 숫ìžì—¬ì•¼ 한다. 다른 경우는 함수가 NULLì„ ë¦¬í„´í•œë‹¤. ë§Œì•½ì— ë£¨ì•„ 변수가 숫ìž(number)ì¸ ê²½ìš° 스íƒì˜ ê°’ì„ ë¬¸ìžì—´ë¡œ 변환해준다. lua_tostring()함수는 완전히 ì •ë ¬ëœ ë£¨ì•„ 환경 안ì—ì„œì˜ ë¬¸ìžì—´ì„ 리턴한다.(This change confuses lua_next when lua_tostring is applied to keys.) ì´ ë¬¸ìžì—´ì€ C처럼 í•­ìƒ ëì— \0를 가지고 있다. 하지만 ì¤‘ê°„ì— \0를 가지고 ìžˆì„ ìˆ˜ë„ ìžˆë‹¤. ë§Œì•½ì— ì¤‘ê°„ì— \0를 가지고 있다는 ê²ƒì„ ëª¨ë¥¸ë‹¤ë©´, lua_strlen()함수를 ì´ìš©í•˜ì—¬ 실재 길ì´ë¥¼ 재 ë³¼ 수 있다. 루아는 개비지 ì»¬ëŸ­ì…˜ì„ í•˜ê¸° 때문 lua_tostringì— ì˜í•´ 얻어진 í¬ì–¸í„°ê°€ 나중ì—ë„ ìœ íš¨í•˜ì§€ëŠ” 않다. 그래서 ë§Œì•½ì— í•¨ìˆ˜ë¥¼ 호출해서 스트ë§ì„ 넘겨 받았다면 ì´ê²ƒì„ 보사해 ë‘ì–´ì—¬ 한다. (í˜¹ì€ ëž˜ì§€ìŠ¤íŠ¸ë¦¬ì— ë“±ë¡í•˜ëŠ” ë°©ë²•ì´ ìžˆë‹¤. (4.8ì ˆì„ ì°¸ì¡°) )

lua_tocfunction() 함수는 스í…ì˜ C함수는 변수로 바꿔준다. ì´ í•¨ìˆ˜ëŠ” C함수여야 한다. 다른 경우는 NULLì„ ë°˜í™˜í•œë‹¤. lua_CFunction í˜•ì— ê´€í•œ ë‚´ìš©ì€ 4.17ì ˆì— ë‚˜ì™€ìžˆë‹¤.

lua_touserdata() 함수는 4.9ì ˆì„ ì°¸ì¡°í•œë‹¤.

8 스íƒìœ¼ë¡œ ê°’ì„ push 하기 #

C ë³€ìˆ˜ê°’ì„ ìŠ¤íƒì— push하기 위해 API는 ì•„ëž˜ì˜ í•¨ìˆ˜ë“¤ì„ ê°€ì§€ê³  있다 :
void lua_pushboolean   (lua_State *L, int b);
void lua_pushnumber    (lua_State *L, lua_Number n);
void lua_pushlstring   (lua_State *L, const char *s, size_t len);
void lua_pushstring    (lua_State *L, const char *s);
void lua_pushnil       (lua_State *L);
void lua_pushcfunction (lua_State *L, lua_CFunction f);
void lua_pushlightuserdata  (lua_State *L, void *p);

ì´ í•¨ìˆ˜ë“¤ì€ C ë³€ìˆ˜ê°’ì„ ë°›ì•„ì„œ 루아 값으로 바꿔서 결과를 스íƒì— 집어넣는다. lua_pushlstring ê³¼ lua_pushstring ì˜ ê²½ìš°ì—는 주어진 문ìžì—´ì— 대하여 특별히 ë‚´ë¶€ì ì¸ ë³µì‚¬ë³¸ì„ ë§Œë“ ë‹¤. lua_pushstringì€ ì ì ˆí•œ C문ìžì—´(NULL-ended 문ìžì—´ì„ ë§í•œë‹¤.)ë§Œ 사용ëœë‹¤. 그리고 lua_pushlstringì˜ ê²½ìš°ì—는 í¬ê¸°ë¥¼ 명시할 수 있다.

그리고 ì—¬ëŸ¬ë¶„ì€ ë˜í•œ "í¬ë§·ëœ" 문ìžì—´ë„ 사용할 수 있다:

const char *lua_pushfstring  (lua_State *L, const char *fmt, ...);
const char *lua_pushvfstring (lua_State *L, const char *fmt, va_list argp);

ì´ ë‘ í•¨ìˆ˜ëŠ” 문ìžì—´ì˜ 형ì‹ì„ 만든 다ìŒì— 만들어진 문ìžì—´ì˜ í¬ì¸í„°ë¥¼ 스íƒì— 집어넣는다. ì´ í•¨ìˆ˜ë“¤ì€ sprintf 그리고 vsprintf와 ìƒë‹¹ížˆ 유사하지만 몇가지 중요한 ì°¨ì´ì ì´ 있다.

결과를 위하여 ê³µê°„ì„ í• ë‹¹í•  필요가 없다.; 결과는 루아 문ìžì—´ì´ ë˜ê³  루아는 ì´ ë¬¸ìžì—´ì˜ 메모리를 관리해 준다. 변환 명시ìžë“¤ì´ 제한ì ì´ë‹¤. 플랙ì´ë‚˜, 너비, ì •í™•ë„ ë“±ì„ ëª…ê¸°í•  수 없다. ì´ ë³€í™˜ 명시ìžë“¤ì€ %% (% ì— ë¬¸ìžì—´), %s (ê¸¸ì´ ì œí•œ 없는 NULL-로 ë나는 문ìžì—´), %f (lua_Number), %d (정수), %c (문ìž)ê°€ 있다.

9 개비지 ì»¬ëž™ì…˜ì„ ì¡°ì ˆí•˜ê¸° #

Lua uses two numbers to control its garbage collection: the count and the threshold (see Section 2.6). The first counts the ammount of memory in use by Lua; when the count reaches the threshold, Lua runs its garbage collector. After the collection, the count is updated, and the threshold is set to twice the count value.

You can access the current values of these two numbers through the following functions:
int  lua_getgccount (lua_State *L);
int  lua_getgcthreshold (lua_State *L);

Both return their respective values in Kbytes. You can change the threshold value with
void  lua_setgcthreshold (lua_State *L, int newthreshold);

Again, the newthreshold value is given in Kbytes. When you call this function, Lua sets the new threshold and checks it against the byte counter. If the new threshold is smaller than the byte counter, then Lua immediately runs the garbage collector. In particular lua_setgcthreshold(L,0) forces a garbage collectiion. After the collection, a new threshold is set according to the previous rule.

10 유저ë°ì´íƒ€ 루아 타입 #

유저ë°ì´íƒ€ íƒ€ìž…ì€ ë£¨ì•„ë‚´ì—서 C 언어 ê°’ì„ ì˜ë¯¸í•œë‹¤. 루아는 "full"ê³¼ "light"ì˜ ë‘가지 íƒ€ìž…ì˜ ìœ ì €ë°ì´íƒ€ë¥¼ ì§€ì›í•œë‹¤.

"full" 유저ë°ì´íƒ€ëŠ” 루아 í™˜ê²½ë‚´ì— ìƒì„±ëœ ë©”ëª¨ë¦¬ì˜ ë¸”ëŸ­ì„ ì˜ë¯¸í•œë‹¤. ì´ê²ƒì€ (í…Œì´ë¸”ê³¼ ê°™ì€) 루아 ê°ì²´ë¡œ 간주ë˜ë©° 다ìŒê³¼ ê°™ì€ íŠ¹ì§•ì„ ê°€ì§„ë‹¤.
  • 루아 코드내ì—서 ìƒì„±ì´ 가능하다.
  • ìžì‹ ë§Œì˜ 메타테ì´ë¸”ì„ ê°€ì§€ê³  있다. 그러므로, ê°œë¹„ì§€ì»¬ë ‰ì…˜ì´ ì‹¤í–‰ë  ë•Œë¥¼ ê°ì§€í•  수 있다.
  • ìƒì„±ëœ 후ì—는 ìžê¸°ìžì‹ ë§Œì˜ 메모리 주소를 가진다. 즉, ê°ê°ì˜ ì¸ìŠ¤í„´ìŠ¤ê°€ 별ë„로 ìƒì„±ëœë‹¤.

"light" 유저ë°ì´íƒ€ëŠ” C 언어ì—ì„œì˜ í¬ì¸í„°ë¥¼ ì˜ë¯¸í•œë‹¤. ì´ê²ƒì€ 단지 (숫ìžì™€ ê°™ì€) 값으로 간주ë˜ë©° 다ìŒê³¼ ê°™ì€ íŠ¹ì§•ì´ ìžˆë‹¤.
  • 루아내ì—서 ìƒì„±í•  수 없으며 ê¼­ 외부ì—서 넘겨주어야만 한다.
  • ìžì‹ ë§Œì˜ 메타테ì´ë¸”ì„ ê°€ì§€ê³  있지 않다. 루아내ì—서 ìƒì„±ë  수 없으므로 개비지 컬랙션ë˜ì§€ë„ 않는다.
  • ë§Œì¼ ê°™ì€ ì£¼ì†Œìƒì— ìƒì„±ë˜ì—ˆë‹¤ë©´, ì´ê²ƒì€ 아무리 다른 ì´ë¦„ì„ ë£¨ì•„ë‚´ì— ê°€ì§„ë‹¤í•˜ë”ë¼ë„ ê°™ì€ ë‚´ìš©ì„ ê°€ì§€ê²Œ ëœë‹¤. (í¬ì¸í„°ì´ë‹ˆ 당연한 얘기.)

루아 코드내ì—서는 유저ë°ì´íƒ€ê°€ "full"ì¸ì§€ "light"ì¸ì§€ 알 ë°©ë²•ì€ ì—†ë‹¤ - 둘다 무조껀 유저ë°ì´íƒ€ê°ì²´ë¡œì„œ 간주ëœë‹¤. C 코드ìƒì—서는 lua_type() API를 사용하여 알수 있으며, 함수를 실행하면 fullì¼ ê²½ìš° LUA_TUSERDATA, lightë©´ LUA_LIGHTUSERDATA으로 반환한다.

ë‹¤ìŒ í•¨ìˆ˜ë¥¼ 사용하여 C 코드ìƒì—서 full 유저ë°ì´íƒ€ë¥¼ ìƒì„±í•  수 있다.
void *lua_newuserdata (lua_State *L, size_t size);

ì´ í•¨ìˆ˜ëŠ” 루아 í™˜ê²½ë‚´ì— ì£¼ì–´ì§„ í¬ê¸°ë§Œí¼ 새로운 ë©”ëª¨ë¦¬ë¸”ëŸ­ì„ í• ë‹¹í•˜ê³ , 스íƒì— ìƒì„±ëœ ë¸”ëŸ­ì˜ ì£¼ì†Œë¥¼ 가진 유저ë°ì´íƒ€ë¥¼ 푸쉬한 후, ìƒì„±ëœ ë¸”ëŸ­ì˜ ì£¼ì†Œê°’ì„ ë°˜í™˜í•œë‹¤. light 유저ë°ì´íƒ€ë¥¼ 스íƒì— 푸쉬하려면 lua_pushlightuserdata() API를 사용하면 ëœë‹¤. (4.7장 참조)

lua_touserdata() API함수(4.6장 참조)는 유저ë°ì´íƒ€ì˜ ê°’ì„ ë°˜í™˜í•œë‹¤. full 유저ë°ì´íƒ€ìƒì— ì´ í•¨ìˆ˜ë¥¼ 사용하면, 해당 메모리 ë¸”ëŸ­ì˜ í¬ì¸í„°ë¥¼ 반환하고, lightì— ì‚¬ìš©í•˜ë©´ ê·¸ì— í•´ë‹¹í•˜ëŠ” í¬ì¸í„°ê°’ì„ ë°˜í™˜í•œë‹¤. 유저ë°ì´íƒ€ 타입 ì´ì™¸ì˜ ê°’ì— ì´ í•¨ìˆ˜ë¥¼ 사용하면 NULLì´ ë°˜í™˜ëœë‹¤.

루아가 full 유저ë°ì´íƒ€ë¥¼ 개비지 ì»¬ëž™ì…˜ì„ ì ìš©í•  때ì—는 ê·¸ 유저ë°ì´íƒ€ì— 대한 gc 메타메소드를 실행하며, ê·¸ëŸ°ë‹¤ìŒ ê·¸ì— í•´ë‹¹í•˜ëŠ” 메모리를 해제한다. (앞서 ë§í–ˆë“¯ì´, light 유저ë°ì´íƒ€ëŠ” 개비지 컬랙션ë˜ì§€ 않는다. 그러므로 호스트 프로그램간 í†µì‹ ì— ê°€ìž¥ 유용하게 ì“°ì¼ ìˆ˜ 있다.)

11 메타테ì´ë¸” #

ë‹¤ìŒ í•¨ìˆ˜ë“¤ì€ í•´ë‹¹ ì¸ë±ìŠ¤ì˜ ê°ì²´ì— 대한 메타테ì´ë¸”ì„ ë‹¤ë£¨ê¸° 위한 것들ì´ë‹¤.
int lua_getmetatable (lua_State *L, int objindex);
int lua_setmetatable (lua_State *L, int objindex);

양쪽 함수 ëª¨ë‘ ì²˜ë¦¬ë¥¼ 위한 ì ë²•한 indexë¡œì¨ objindex를 요구한다. lua_getmetatable() 함수는 지정한 objindexì— í•´ë‹¹ë˜ëŠ” ê°ì²´ì˜ 메타테ì´ë¸”ì„ ìŠ¤íƒì— 푸쉬한다. lua_setmetatable() 함수는 현재 스íƒì˜ topìœ„ì¹˜ì— ìžˆëŠ” í…Œì´ë¸”ì„ í•´ë‹¹ ê°ì²´ë¥¼ 위한 ì‹ ê·œ 메타테ì´ë¸”로 설정한다. 그리고 í…Œì´ë¸”ì„ pop처리한다. 즉, ì¼ë°˜ì ìœ¼ë¡œ ì‹ ê·œ 메타테ì´ë¸”ì„ ë“±ë¡í•˜ëŠ” 코드는 다ìŒê³¼ 같다.
newuserdata = (char *) lua_newuserdata(L, userdatasize);   -- ì‹ ê·œ full 유저ë°ì´íƒ€ë¥¼ ìƒì„±í•œ 후 스íƒì˜ 맨 ì•žì— í‘¸ì‰¬.
lua_newtable(L);              -- ì‹ ê·œ 빈 í…Œì´ë¸”ì„ ìƒì„±í•œ 후 스íƒì˜ topì— í‘¸ì‰¬.
lua_setmetatable(L, -2);      -- ì´ ì‹œì ì—서 ì•žì— ìƒì„±í•œ í…Œì´ë¸”ì€ newuserdataì˜ ë©”íƒ€í…Œì´ë¸”로 등ë¡ëœë‹¤. (popë˜ì–´ 없어진다.)

-- ì´ì œ 스íƒì˜ topì€ newuserdataì´ë‹¤.

만약 ê°ì²´ê°€ 메타테ì´ë¸”ì„ ê°€ì§€ê³  있지 않다면, lua_getmetatable() 함수는 0ì„ ë°˜í™˜í•˜ë©°, 스íƒì—는 ì•„ë¬´ê²ƒë„ í‘¸ì‰¬í•˜ì§€ 않는다. 주어진 ê°ì²´ì— 메타테ì´ë¸”ì„ ì„¤ì •í•  수 없는 경우(다시ë§í•˜ë©´, ê°ì²´ê°€ 유저ë°ì´íƒ€ì™€ í…Œì´ë¸” ì–´ëŠ ìª½ë„ ì•„ë‹ê²½ìš°)ì—는 lua_setmetatable() 함수는 0ì„ ë°˜í™˜í•œë‹¤. (당연한 얘기지만, ì´ë•Œì—는 ì•„ë¬´ê²ƒë„ popë˜ì§€ 않는다.)

12 루아 ì²­í¬ë¥¼ 로딩하기 #

You can load a Lua chunk with
typedef const char * (*lua_Chunkreader) (lua_State *L, void *data, size_t *size);

int lua_load (lua_State *L, lua_Chunkreader reader, void *data, const char *chunkname);

lua_load uses the reader to read the chunk. Everytime it needs another piece of the chunk, it calls the reader, passing along its data parameter. The reader must return a pointer to a block of memory with a new part of the chunk, and set size to the block size. To signal the end of the chunk, the reader must return NULL. The reader function may return pieces of any size greater than zero. In the current implementation, the reader function cannot call any Lua function; to ensure that, it always receives NULL as the Lua state.

lua_load automatically detects whether the chunk is text or binary, and loads it accordingly (see program luac).

The return values of lua_load are:

  • 0 - no errors;
  • LUA_ERRSYNTAX - syntax error during pre-compilation.
  • LUA_ERRMEM - memory allocation error.

If there are no errors, the compiled chunk is pushed as a Lua function on top of the stack. Otherwise, an error message is pushed. The chunkname is used for error messages and debug information (see Section 5).

See the auxiliar library (lauxlib) for examples of how to use lua_load, and for some ready-to-use functions to load chunks from files and from strings.

13 í…Œì´ë¸” 관리 #

í…Œì´ë¸”ì€ ë‹¤ìŒ í•¨ìˆ˜ë¥¼ 사용하여 ìƒì„±í•  수 있다.
void lua_newtable (lua_State *L);

ì´ í•¨ìˆ˜ëŠ” 새로운 텅빈 í…Œì´ë¸”ì„ ìƒì„±í•˜ê³  ê·¸ê²ƒì„ ìŠ¤íƒì— push한다. 스íƒì–´ë”˜ê°€ì— 위치한 í…Œì´ë¸”로부터 ê°’ì„ ì½ê¸° 위해서는 ë‹¤ìŒ í•¨ìˆ˜ë¥¼ 호출하ë¼. index는 í…Œì´ë¸”ì´ ìœ„ì¹˜í•œ ì¸ë±ìŠ¤ë¥¼ ì˜ë¯¸í•œë‹¤.
void lua_gettable (lua_State *L, int index);

ì´ í•¨ìˆ˜ëŠ” 스íƒìœ¼ë¡œë¶€í„° key를 pop 처리 한후, ê·¸ keyì— í•´ë‹¹í•˜ëŠ” í…Œì´ë¸”ì˜ ë‚´ìš©ë“¤ì„ ë‹¤ì‹œ 스íƒì— push한다. í…Œì´ë¸”ì€ ìŠ¤íƒìƒì— ìžˆì—ˆë˜ ìœ„ì¹˜ì— ê·¸ëŒ€ë¡œ 남겨진다. ì´ëŸ° ì ì€ í…Œì´ë¸”로부터 ì—¬ëŸ¬ê°œì˜ ê°’ì„ ì–»ëŠ”ë° ìœ ìš©í•˜ê²Œ ì‚¬ìš©ë  ìˆ˜ 있다.

루아ìƒì—서 í…Œì´ë¸”ì„ ì–µì„¸ìŠ¤í•  때와 ê°™ì´, ì´ í•¨ìˆ˜ëŠ” "gettable"ì´ë‚˜ "index" ì´ë²¤íŠ¸ì— í•´ë‹¹í•˜ëŠ” 메타메소드를 기ë™í•  ìˆ˜ë„ ìžˆë‹¤. ì–´ë–¤ ë©”íƒ€ë©”ì†Œë“œë„ ì‹¤í–‰í•˜ì§€ 않으면서 특정 í…Œì´ë¸” keyì— í•´ë‹¹í•˜ëŠ” 실제 ê°’ì„ ì–»ê¸° 위해서는 ë‹¤ìŒ í•¨ìˆ˜ë¥¼ 사용한다.
void lua_rawget (lua_State *L, int index);

ìŠ¤íƒ ì–´ë”˜ê°€ì— ìœ„ì¹˜í•œ í…Œì´ë¸”로 ê°’ì„ ì €ìž¥í•˜ë ¤ë©´, keyê°’ê³¼ ê·¸ì— ë”°ë¥¸ ê°’ì„ ìŠ¤íƒì— 순서대로 push 하고 ë‹¤ìŒ í•¨ìˆ˜ë¥¼ 호출하면 ëœë‹¤. (index는 í…Œì´ë¸”ì´ ìœ„ì¹˜í•œ 스íƒìƒì˜ ì¸ë±ìФì´ë‹¤.)
void lua_settable (lua_State *L, int index);

ì´ í•¨ìˆ˜ëŠ” ì‹¤í–‰í›„ì— pushí–ˆë˜ key와 ê·¸ì— ë”°ë¥¸ ê°’ì„ pop 처리한다. í…Œì´ë¸”ì€ ì›ëž˜ ìžˆë˜ ìžë¦¬ì— 남겨진다. ì´ í•¨ìˆ˜ë„ ì—­ì‹œ "settable" ë˜ëŠ” "newindex" 메타메소드를 기ë™ì‹œí‚¬ 수 있다. ì´ ë©”íƒ€ë©”ì†Œë“œë¥¼ 기ë™í•˜ì§€ 않으면서 ê°’ì„ ì„¤ì •í•˜ë ¤ë©´ ë‹¤ìŒ í•¨ìˆ˜ë¥¼ 실행하면 ëœë‹¤.
void lua_rawset (lua_State *L, int index);

í…Œì´ë¸”ì˜ ë‚´ìš©ì„ í›‘ìœ¼ë ¤ë©´ ë‹¤ìŒ í•¨ìˆ˜ë¥¼ 사용한다. index는 í…Œì´ë¸”ì´ ìœ„ì¹˜í•œ 스íƒìƒì˜ ì¸ë±ìФì´ë‹¤.
int lua_next (lua_State *L, int index);

ì´ í•¨ìˆ˜ëŠ” 스íƒìœ¼ë¡œë¶€í„° keyê°’ì„ pop한 후, popì²˜ë¦¬ëœ Keyê°’ì˜ ë‹¤ìŒ ê°’ì— í•´ë‹¹ë˜ëŠ” keyê°’ê³¼ ê·¸ì— ëŒ€ì‘ë˜ëŠ” ì‹¤ì œê°’ì„ push한다. ë§Œì¼ ë”ì´ìƒ ë‹¤ìŒ ìš”ì†Œê°€ 없으면 0ì„ ë°˜í™˜í•œë‹¤. (ì´ë•ŒëŠ” ì•„ë¬´ê²ƒë„ pushë˜ì§€ 않는다.) 가장 처ìŒë¶€í„° 훑기 위해서는 nilì„ push한 후 ì´ í•¨ìˆ˜ë¥¼ 사용하ë¼.

전형ì ì¸ í…Œì´ë¸”ì˜ í›‘ê¸° ìž‘ì—…ì€ ë‹¤ìŒê³¼ 같다.
/* 스íƒë‚´ì—서 í…Œì´ë¸”ì€ ì¸ë±ìФ tì— ìœ„ì¹˜í•´ìžˆë‹¤. */
lua_pushnil(L);  /* 첫번째 Key를 훑ë„ë¡ ì„¤ì • */
while (lua_next(L, t) != 0) 
{
     /* keyê°’ì€ ì¸ë±ìФ -2ì— ìžˆê³  대ì‘ë˜ëŠ” ê°’ì€ ì¸ë±ìФ -1ì— ìžˆë‹¤. */
     printf("%s - %s\n", lua_typename(L, lua_type(L, -2)), lua_typename(L, lua_type(L, -1)));
     lua_pop(L, 1);  /* í‚¤ì— í•´ë‹¹ë˜ëŠ” ê°’ë§Œ 제거한다. ë‹¤ìŒ í›‘ëŠ” 단계를 실행하기 위해 현재 keyê°’ì€ ë‚¨ê²¨ë‘”ë‹¤. */
}

ì£¼ì˜ : í…Œì´ë¸”ì„ í›‘ëŠ” 작업중ì—는 keyê°’ì— ì‹¤ì œ keyê°’ì´ ë¬¸ìžì—´ì¸ì§€ 확실하지 않으면 lua_tostring() 함수를 실행하지 ë§ì•„ë¼. lua_tostring()ì€ ì£¼ì–´ì§„ ì¸ë±ìŠ¤ì˜ ê°’ì„ ë¬¸ìžì—´ë¡œ 변환시킨다. 즉, ì´ëŸ° 경우ì—는 ì›ëž˜ í‚¤ê°’ì´ ë¬¸ìžì—´ì´ 아니ë¼ë©´ ë‹¤ìŒ lua_next() í˜¸ì¶œì‹œì— í˜¼ëž€ì„ ê°€ì ¸ì˜¬ 수 있다.

14 ì „ì—­ 변수 í…Œì´ë¸”ì„ ê´€ë¦¬í•˜ê¸° #

모든 전역변수는 ìƒì£¼í•˜ê³  있는 루아 í…Œì´ë¸”ì•ˆì— ìœ ì§€ëœë‹¤. ì´ í…Œì´ë¸”ì€ ì–¸ì œë‚˜ 가짜 ì¸ë±ìФ LUA_GLOBALSINDEXì— ìœ„ì¹˜í•œë‹¤.

ì „ì—­ ë³€ìˆ˜ì˜ ê°’ì„ ì–µì„¸ìŠ¤í•˜ê±°ë‚˜ 변경하기 위해서 전역변수 í…Œì´ë¸”ì— í†µìƒì ì¸ í…Œì´ë¸” ëª…ë ¹ì„ ì‚¬ìš©í•  수 있다. 예를 들면 ì „ì—­ë³€ìˆ˜ì˜ ê°’ì„ ì–µì„¸ìŠ¤í•˜ê¸°ìœ„í•˜ì—¬ 다ìŒê³¼ ê°™ì´ ì‹¤í–‰í•˜ë¼.
lua_pushstring(L, varname);
lua_gettable(L, LUA_GLOBALSINDEX);

루아 ì“°ë ˆë“œì˜ ì „ì—­ í…Œì´ë¸”ì€ lua_replace() 함수를 사용하여 변경하는 ê²ƒì´ ê°€ëŠ¥í•˜ë‹¤.

15 í…Œì´ë¸”ì€ ë°°ì—´ë¡œì¨ ì‚¬ìš©í•˜ê¸° #

API는 ë‹¤ìŒ í•¨ìˆ˜ë“¤ì„ ì œê³µí•˜ì—¬ 루아 í…Œì´ë¸”ì„ ë°°ì—´ë¡œ 사용하는 ê²ƒì„ ë•는다. ì´ë•Œì—는 í…Œì´ë¸”ì€ ë‹¨ì§€ 숫ìžë¡œë§Œ ì¸ë±ìФë˜ì–´ìžˆì–´ì•¼ 한다.
void lua_rawgeti (lua_State *L, int index, int n);
void lua_rawseti (lua_State *L, int index, int n);

lua_rawgeti()는 index ì¸ë±ìŠ¤ì— ìœ„ì¹˜í•œ í…Œì´ë¸”ì˜ n번째 ìš”ì†Œì˜ ê°’ì„ push한다. lua_rawseti()는 index ì¸ë±ìŠ¤ì— ìœ„ì¹˜í•œ í…Œì´ë¸”ì˜ n번째 ìš”ì†Œì˜ ê°’ì„ ìŠ¤íƒì˜ topì— ìœ„ì¹˜í•œ 값으로 ë®ì–´ì“°ê³ , pop처리한다. (즉, 설정할 ê°’ì„ push 한 후 ì´ í•¨ìˆ˜ë¥¼ 실행하면 ëœë‹¤. ì‹¤í–‰í›„ì— push한 ê°’ì€ ì—†ì–´ì§„ë‹¤.)

16 Cì—서 루아 함수를 호출하기 #

루아내ì—서 ì •ì˜ëœ 함수와 ë£¨ì•„ë‚´ì— ë“±ë¡ëœ C í•¨ìˆ˜ë“¤ì€ í˜¸ìŠ¤íŠ¸ 프로그램ì—서 í˜¸ì¶œì´ ê°€ëŠ¥í•˜ë‹¤. ì´ê²ƒì€ 다ìŒê³¼ ê°™ì€ ê·œì¹™ì„ ì‚¬ìš©í•˜ì—¬ 실행ëœë‹¤.
  1. í˜¸ì¶œë  í•¨ìˆ˜ë¥¼ 스íƒì— push한다.
  2. í•¨ìˆ˜ì˜ ì¸ìžë¡œ ì“°ì¼ ê°’ë“¤ì„ ì •ì˜ëœ ì¸ìž 순서대로 push한다. 다시ë§í•˜ë©´, 첫번째 ì •ì˜ëœ ì¸ìžëŠ” ë§¨ì²˜ìŒ push 한다.
  3. 마지막으로 lua_call()ì„ ì‹¤í–‰í•œë‹¤. nargs는 실행할 í•¨ìˆ˜ì˜ ì¸ìž 개수를 ì˜ë¯¸í•œë‹¤. nresults는 함수가 ì‹¤í–‰ëœ í›„ì˜ ë°˜í™˜ê°’ì˜ ê°œìˆ˜ë¥¼ ì˜ë¯¸í•œë‹¤. (LUA_MULTRET로 지정할 경우는 예외. ì´ ê²½ìš°ì—는, 모든 ë°˜í™˜ê°’ì´ pushëœë‹¤. 루아는 ë°˜í™˜ê°’ë“¤ë•Œë¬¸ì— ìŠ¤íƒ ì˜¤ë²„í”Œë¡œìš°ê°€ ì¼ì–´ë‚˜ëŠ”ì§€ 살펴보게 ëœë‹¤.) í•¨ìˆ˜ì˜ ì‹¤í–‰ê²°ê³¼ê°’ì€ ìŠ¤íƒì— 순서대로 pushëœë‹¤. (첫번째 ê²°ê³¼ê°’ì´ ë§¨ì²˜ìŒ pushëœë‹¤.) 그러므로 호출 결과값중 가장 마지막 ê²°ê³¼ê°’ì´ topì— ìœ„ì¹˜í•˜ê²Œ ëœë‹¤. lua_call()ì˜ í•¨ìˆ˜ì •ì˜ëŠ” 다ìŒê³¼ 같다.
    void lua_call(lua_State *L, int nargs, int nresults);
    

ë‹¤ìŒ ì˜ˆì œëŠ” ì•„ëž˜ì˜ ë£¨ì•„ì½”ë“œì™€ ë™ì¼í•˜ê²Œ 수행ë˜ë„ë¡ ì–´ë–»ê²Œ 호스트 í”„ë¡œê·¸ëž¨ì„ ìž‘ì„±í•˜ëŠ” 가를 보여준다.
a = f("how", t.x, 14)

Cì—서는,
lua_pushstring(L, "t");
lua_gettable(L, LUA_GLOBALSINDEX);         /* ì „ì—­ 't' (ë‚˜ì¤‘ì— ì‚¬ìš©) */
lua_pushstring(L, "a");                                  /* 변수명 */
lua_pushstring(L, "f");                                  /* 함수명 */
lua_gettable(L, LUA_GLOBALSINDEX);               /* í˜¸ì¶œë  í•¨ìˆ˜ë¥¼ 찾았다 */
lua_pushstring(L, "how");                                 /* 첫번째 ì¸ìžê°’ */
lua_pushstring(L, "x");             /* "x"ë¼ëŠ” ì´ë¦„ì˜ ë³€ìˆ˜ê°’ì„ tí…Œì´ë¸”ì—서 ì°¾ì„ ê²ƒì´ë‹¤ */
lua_gettable(L, -5);                      /* t.xì˜ ê°’ì„ push한다. (ë‘번째 ì¸ìž) */
lua_pushnumber(L, 14);                                    /* 세번째 ì¸ìžê°’ */
lua_call(L, 3, 1);         /* ìž, 3ê°œì˜ ì¸ìžì™€ 1ê°œì˜ ë°˜í™˜ê°’ì„로 실행ë˜ë„ë¡ í•¨ìˆ˜ 실행! */
lua_settable(L, LUA_GLOBALSINDEX);             /* ì „ì—­ í…Œì´ë¸”ìƒì—서 "a"ì—다가 ê²°ê³¼ê°’ì„ ì„¤ì •í•œë‹¤. */
lua_pop(L, 1);                               /* 스íƒìœ¼ë¡œ 부터 "t"를 제거한다. */

위 코드가 "균형ì ìœ¼ë¡œ" 실행ëœë‹¤ëŠ” ì ì— 주목하ë¼. ì½”ë“œì˜ ë§ˆì§€ë§‰ì—는 스íƒì´ ì›ëž˜ì˜ ìƒíƒœë¡œ ëŒì•„가는 ê²ƒì„ ì•Œ 수 있다. ì´ê²ƒì€ ì¢‹ì€ í”„ë¡œê·¸ëž˜ë° ì—°ìŠµì´ ë  ìˆ˜ 있다. (단지 루아 APIì— ì˜í•´ 제공ë˜ëŠ” 함수들로만 ì´ ì˜ˆì œë¥¼ 구현했다. ì¼ë°˜ì ìœ¼ë¡œ í”„ë¡œê·¸ëž˜ë¨¸ë“¤ì€ ë£¨ì•„ì˜ ìƒìœ„레벨 억세스를 제공하는 몇가지 매í¬ë¡œë“¤ê³¼ ë³´ì¡° í•¨ìˆ˜ë“¤ì„ ì‚¬ìš©í•œë‹¤. 사용한 예를 ë‹¤ìŒ ì´ì–´ì§€ëŠ” 예제를 참조하ë¼.)

ë§Œì¼ ë‹¤ìŒê³¼ ê°™ì€ ë£¨ì•„ 함수가 ì„ ì–¸ë˜ì–´ìžˆë‹¤ê³  가정한다면,
function calcexam(x, y)
  return (x^2 + y)
end

ì´ë¥¼ 호출하는 C 소스는 다ìŒê³¼ ê°™ì´ ì ì„ 수 있다.
lua_getglobal(L, "calcexam"); // calcexam 함수를 사용하는 것으로 설정
if (lua_isfunction(L, 1))     // 혹시나 함수타입ì¸ì§€ 검사해본다.
{
    lua_pushnumber(L, 10);   // 첫번째 ì¸ìžëŠ” 10으로 설정
    lua_pushnumber(L, 2);    // ë‘번째 ì¸ìžëŠ” 2로 설정
    lua_call(L, 2, 1);       // 함수 실행!
    int result = (int)lua_tonumber(L, -1);  // ê²°ê³¼ê°’ì„ resultì— ë‹´ëŠ”ë‹¤. ì•„ë§ˆë„ 102ê°€ 담길 것ì´ë‹¤.
    lua_pop(L, 1);           // ë§¨ì²˜ìŒ ì¶”ê°€í–ˆë˜ í•¨ìˆ˜ë¥¼ 스íƒì—서 pop 처리한다.
}

17 Protected Calls #

When you call a function with lua_call, any error inside the called function is propagated upwards (with a longjmp). If you need to handle errors, then you should use lua_pcall:
int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc);

Both nargs and nresults have the same meaning as in lua_call. If there are no errors during the call, lua_pcall behaves exactly like lua_call. Like lua_call, lua_pcall always removes the function and its arguments from the stack. However, if there is any error, lua_pcall catches it, pushes a single value at the stack (the error message), and returns an error code. If errfunc is 0, then the error message returned is exactly the original error message. Otherwise, errfunc gives the stack index for an error handler function. (In the current implementation, that index cannot be a pseudo-index.) In case of runtime errors, that function will be called with the error message, and its return value will be the message returned by lua_pcall.

Typically, the error handler function is used to add more debug information to the error message, such as a stack traceback. Such information cannot be gathered after the return of lua_pcall, since by then the stack has unwound.

The lua_pcall function returns 0 in case of success, or one of the following error codes (defined in lua.h):

  • LUA_ERRRUN - a runtime error.
  • LUA_ERRMEM - memory allocation error. For such errors, Lua does not call the error handler function.
  • LUA_ERRERR - error while running the error handler function.

Some special Lua functions have their own C interfaces. The host program can generate a Lua error calling the function
void lua_error (lua_State *L, const char *message);

This function never returns. If lua_error is called from a C function that has been called from Lua, then the corresponding Lua execution terminates, as if an error had occurred inside Lua code. Otherwise, the whole host program terminates with a call to exit(EXIT_FAILURE). Before terminating execution, the message is passed to the error handler function, _ERRORMESSAGE (see Section 3.6). If message is NULL, then _ERRORMESSAGE is not called. The function
void lua_concat (lua_State *L, int n);

concatenates the n values at the top of the stack, pops them, and leaves the result at the top. If n is 1, the result is that single string (that is, the function does nothing); if n is 0, the result is the empty string. Concatenation is done following the usual semantics of Lua (see Section 3.4.4).

18 C 함수를 ë£¨ì•„ì— ë“±ë¡í•˜ê¸° #

루아는 C언어로 ìž‘ì„±ëœ í•¨ìˆ˜ë“¤ë¡œ í™•ìž¥ë  ìˆ˜ 있다. ì´ í•¨ìˆ˜ë“¤ì€ ë°˜ë“œì‹œ 아래와 ê°™ì´ ì •ì˜ëœ lua_CFunction 타입으로 ì •ì˜ë˜ì–´ì•¼ 한다.
typedef int (*lua_CFunction) (lua_State *L);

루아 ë‚´ì— ì‚¬ìš©ë  C 함수는 언제나 루아 í™˜ê²½ì„ ì˜ë¯¸í•˜ëŠ” state 변수를 ì¸ìžë¡œ 받고, ë°˜í™˜ê°’ì˜ ê°œìˆ˜ë¥¼ ì˜ë¯¸í•˜ëŠ” integer ê°’ì„ ë°˜í™˜í•˜ëŠ” 구조를 가진다.

루아와 ì•Œë§žì€ í†µì‹ ì„ í•˜ê¸° 위해서는 C 함수는 다ìŒê³¼ ê°™ì€ í”„ë¡œí† ì½œì„ ë”°ë¥¸ë‹¤ : C 함수는 스íƒì„ 사용하여 루아로부터 í•¨ìˆ˜ì˜ ì¸ìžë“¤ì„ 넘겨받는다. ê·¸ 순서는 순방향(가장 ì²˜ìŒ ì¸ìžê°€ 가장 먼저 푸쉬ëœë‹¤.)으로 지정ëœë‹¤. 루아로 ê°’ì„ ë°˜í™˜í•˜ê¸° 위해서는 C 함수는 스íƒìœ¼ë¡œ ê·¸ ë°˜í™˜ê°’ë“¤ì„ í‘¸ì‰¬í•œë‹¤. ì´ ìˆœì„œë„ ì—­ì‹œ 순방향ì´ë‹¤. (가장 첫번째 ë°˜í™˜ê°’ì´ ê°€ìž¥ 먼저 푸쉬ëœë‹¤.) 루아ì—서 ì„ ì–¸ëœ í•¨ìˆ˜ì™€ ê°™ì´, 루아내ì—서 ì‚¬ìš©ë  C í•¨ìˆ˜ë„ ì—¬ëŸ¬ê°œì˜ ê²°ê³¼ê°’ì„ ë°˜í™˜í•  수 있다.

예를 들어 ì—¬ëŸ¬ê°œì˜ ìˆ˜ì¹˜ë¥¼ 받아 í‰ê· ê³¼ 합계를 반환하는 ë‚´ìš©ì˜ ë‹¤ìŒê³¼ ê°™ì€ í•¨ìˆ˜ë¥¼ ì •ì˜í•  수 있다.
static int foo (lua_State *L) {
   int n = lua_gettop(L);    /* ì¸ìžì˜ 개수 */
   lua_Number sum = 0;
   int i;
   for (i = 1; i <= n; i++) 
   {
      if (!lua_isnumber(L, i)) 
      {
         lua_pushstring(L, "incorrect argument to function `average'");
         lua_error(L);
      }
      sum += lua_tonumber(L, i);
   }
   lua_pushnumber(L, sum/n);        /* 첫번째 반환값 */
   lua_pushnumber(L, sum);         /* ë‘번째 반환값 */
   return 2;                   /* ë°˜í™˜ê°’ì˜ ê°œìˆ˜ë¥¼ 반환 */
}

루아로 C 함수를 등ë¡í•˜ê¸° 위한 다ìŒê³¼ ê°™ì€ íŽ¸ë¦¬í•œ 매í¬ë¡œê°€ 존재한다.
   #define lua_register(L,n,f) \
               (lua_pushstring(L, n), \
                lua_pushcfunction(L, f), \
                lua_settable(L, LUA_GLOBALSINDEX))
     /* const char *n;   */
     /* lua_CFunction f; */
ì´ ë§¤í¬ë¡œëŠ” 루아 환경 state 변수, 루아내ì—서 사용할 ì´ë¦„, 그리고 í•¨ìˆ˜ì˜ í¬ì¸í„°ë¥¼ ì¸ìžë¡œ 받는다. ë”°ë¼ì„œ ë‹¤ìŒ ì˜ˆëŠ” C 함수 'foo'를 'average'ë¼ëŠ” ì´ë¦„ì˜ ë£¨ì•„ 함수로 등ë¡í•œë‹¤.
lua_register(L, "average", foo);

19 Defining C Closures #

When a C function is created, it is possible to associate some values to it, thus creating a C closure; these values are then accessible to the function whenever it is called. To associate values to a C function, first these values should be pushed onto the stack (when there are multiple values, the first value is pushed first). Then the function
void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);

is used to push the C function onto the stack, with the argument n telling how many values should be associated with the function (lua_pushcclosure also pops these values from the stack); in fact, the macro lua_pushcfunction is defined as lua_pushcclosure with n set to 0. Then, whenever the C function is called, those values are located at specific pseudo-indices. Those pseudo-indices are produced by a macro lua_upvalueindex. The first value associated with a function is at position lua_upvalueindex(1), and so on.

For examples of C functions and closures, see files lbaselib.c, liolib.c, lmathlib.c, and lstrlib.c in the official Lua distribution.

19.1 Registry #

Lua provides a pre-defined table that can be used by any C code to store whatever Lua value it needs to store, especially if the C code needs to keep that Lua value outside the life span of a C function. This table is always located at pseudo-index LUA_REGISTRYINDEX. Any C library can store data into this table, as long as it chooses keys different from other libraries. Typically, you should use as key a string containing your library name, or a light userdata with the address of a C object in your code.

The integer keys in the registry are used by the reference mechanism, implemented by the auxiliar library, and therefore should not be used by other purposes.

Cì—서 루아 함수 호출 코드ì—서 오류를 발견했습니다.

lua_getglobal(L, "calcexam"); // calcexam 함수를 사용하는 것으로 설정 if (lua_isfunction(L, 1)) // 혹시나 함수타입ì¸ì§€ 검사해본다. {
lua_pushnumber(L, 10); // 첫번째 ì¸ìžëŠ” 10으로 설정 lua_pushnumber(L, 2); // ë‘번째 ì¸ìžëŠ” 2로 설정 lua_call(L, 2, 1); // 함수 실행! int result = (int)lua_tonumber(L, -1); // ê²°ê³¼ê°’ì„ resultì— ë‹´ëŠ”ë‹¤. ì•„ë§ˆë„ 102ê°€ 담길 것ì´ë‹¤. lua_pop(L, 1); // ë§¨ì²˜ìŒ ì¶”ê°€í–ˆë˜ í•¨ìˆ˜ë¥¼ 스íƒì—서 pop 처리한다.
}

여기서 lua_isfunction(L, 1)ì€ ë§ˆì§€ë§‰ì— push한 "calcexam"ì˜ íƒ€ìž…ì„ ì²´í¬í•˜ëŠ” 것ì´ë‹ˆ lua_isfunction(L, -1)ì´ ë˜ì–´ì•¼ 합니다. lua_isfunction(L, 1)로 하니까 함수가 아니ë¼ê³  나오ë”êµ°ìš”. 그리고 ë§ˆì§€ë§‰ì˜ // ë§¨ì²˜ìŒ ì¶”ê°€í–ˆë˜ í•¨ìˆ˜ë¥¼ 스íƒì—서 pop 처리한다.ë¼ëŠ” 주ì„ì€ í•¨ìˆ˜ë¥¼ pop하는 ê²ƒì´ ì•„ë‹ˆë¼ ë¦¬í„´ê°’ì„ pop처리한다고 해야겠죠. -- 211.196.83.47 2004-12-01

현재 메뉴얼 소스ìžì²´ì— 버그가 있는 모양입니다. 퀵 ë ˆí¼ëŸ°ìФ 형태로 ì œ ë‚˜ë¦„ëŒ€ë¡œì˜ ë©”ë‰´ì–¼ì„ ì •ë¦¬ì¤‘ìž…ë‹ˆë‹¤. 그걸 ìœ„í‚¤ì— ì˜¬ë¦¬ë©´ ì´ ê¸€ì€ ì§€ìš¸ 예정입니다. -- redpixel 2004-12-01

Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2010-10-28 12:42:52
Processing time 0.6685 sec