
1. 개요
이 문서는 ARM 보드에서 동작하는 C 프로그램이 루아 스크립트를
호출하여 실행한 후 루아 스크립트에서 선언된 변수를 가져 오는 방법을
기술 합니다.
이 문서에서는 다음과 같은 내용을 다룹니다.
* 루아 스크립트 라이브러리를 포함하는 C 컴파일 용 Makefile
* 루아 스크립트를 호출하고 값을 얻어 오는 C 샘플 main.c
* 호출 되는 루아 스크립트 run.lua
2. 실습 구성
다음과 같은 디렉토리 구성을 하였습니다.
/project/lua/sample_lua_arm/lua_include : LUA 헤더 파일 모음
/project/lua/sample_lua_arm/lua_lib : LUA 라이브러리 소스 모음
/project/lua/sample_lua_arm/lua_samples : 앞으로 진행할 강좌의 소스 들
3. 기본 샘플 구성
소스는 다음 디렉토리에 위치 합니다.
/project/lua/sample_lua_arm/lua_samples/030_get_value_from_script
이 디렉토리에는 다음과 같은 파일이 있습니다.
Makefile
main.c
run.lua
4. 소스들
Makefile
CROSS_PREFIX = arm-linux
TARGET = app_run_lua
TARGET_NFS = /nfs/lua
C_SRCS =
C_SRCS += main.c
LUA_SRCS = run.lua
# LUA Support -- CORE
C_SRCS += ../../lua_lib/lapi.c
C_SRCS += ../../lua_lib/lcode.c
C_SRCS += ../../lua_lib/ldebug.c
C_SRCS += ../../lua_lib/ldo.c
C_SRCS += ../../lua_lib/ldump.c
C_SRCS += ../../lua_lib/lfunc.c
C_SRCS += ../../lua_lib/lgc.c
C_SRCS += ../../lua_lib/llex.c
C_SRCS += ../../lua_lib/lmem.c
C_SRCS += ../../lua_lib/lobject.c
C_SRCS += ../../lua_lib/lopcodes.c
C_SRCS += ../../lua_lib/lparser.c
C_SRCS += ../../lua_lib/lstate.c
C_SRCS += ../../lua_lib/lstring.c
C_SRCS += ../../lua_lib/ltable.c
C_SRCS += ../../lua_lib/ltm.c
C_SRCS += ../../lua_lib/lundump.c
C_SRCS += ../../lua_lib/lvm.c
C_SRCS += ../../lua_lib/lzio.c
# LUA Support -- LIB
C_SRCS += ../../lua_lib/lauxlib.c
C_SRCS += ../../lua_lib/lbaselib.c
C_SRCS += ../../lua_lib/ldblib.c
C_SRCS += ../../lua_lib/liolib.c
C_SRCS += ../../lua_lib/lmathlib.c
C_SRCS += ../../lua_lib/loslib.c
C_SRCS += ../../lua_lib/ltablib.c
C_SRCS += ../../lua_lib/lstrlib.c
C_SRCS += ../../lua_lib/loadlib.c
C_SRCS += ../../lua_lib/linit.c
INCLUDES += -I.
INCLUDES += -I/usr/local/include
INCLUDES += -I/usr/$(CROSS_PREFIX)/include
INCLUDES += -I../../include
INCLUDES += -I../../lua_include
LDFLAGS += -L../../lua_lib/
LDFLAGS += -L/usr/$(CROSS_PREFIX)/lib
LIBS = -lm
CFLAGS += $(INCLUDES)
CFLAGS += -Wall -O2 -g
ARFLAGS = rs
#---------------------------------------------------------------------
CC = $(CROSS_PREFIX)-gcc
AR = $(CROSS_PREFIX)-ar rc
AR2 = $(CROSS_PREFIX)-ranlib
RANLIB = $(CROSS_PREFIX)-ranlib
LD = $(CROSS_PREFIX)-ld
NM = $(CROSS_PREFIX)-nm
STRIP = $(CROSS_PREFIX)-strip
OBJCOPY = $(CROSS_PREFIX)-objcopy
CP = cp
MV = mv
#--------------------------------------------------------------------
C_OBJS = $(C_SRCS:%.c=%.o)
%.o:%.c
@echo "Compiling $< ..."
$(CC) -c $(CFLAGS) -o $@ $<
all : $(TARGET) $(LUA_SRCS)
cp $(TARGET) $(TARGET_NFS)
cp $(LUA_SRCS) $(TARGET_NFS)
$(TARGET) : $(C_OBJS)
$(CC) $(LDFLAGS) $(C_OBJS) -o $@ $(LIBS)
dep :
$(CC) -M $(INCLUDES) $(C_SRCS) > .depend
clean:
rm -f *.bak
rm -f *.map
rm -f *.o
rm -f $(C_OBJS)
rm -f $(TARGET) core
distclean: clean
rm -rf .depend
ifeq (.depend,$(wildcard .depend))
include .depend
endif
run.lua
print( "ENTER RUN.LUA" )
print( "BEGIN........." )
A = 1234
B = "Hey"
print( "A =", A );
print( "B =", B );
print( "END........." )
main.c
#include <stdio.h> #include <string.h> #include <lua.h> #include <lauxlib.h> #include <lualib.h>
#define LUA_FILENAME "run.lua"
int main( int argc, char **argv ) { lua_State *L = NULL; int error; int int_value; char *str_value; int len_value; printf( "sample : C function call Lua Script \n" ); L = luaL_newstate(); luaL_openlibs(L); error = luaL_loadfile( L, LUA_FILENAME ) || lua_pcall ( L, 0,0,0 ); printf( "Enter C routine\n" ); if( error ) { fprintf(stderr,"%s\n", lua_tostring(L,-1)); lua_pop(L,1); } lua_getglobal(L, "A" ); // <--- (1) lua_getglobal(L, "B" ); // <--- (2) int_value = lua_tointeger( L, 1 ); // <--- (3) printf( "A = %d\n", int_value ); int_value = lua_tointeger( L, -2 ); printf( "A = %d\n", int_value );
str_value = lua_tostring ( L, 2 ); // <--- (4) printf( "B = %s\n", str_value ); str_value = lua_tostring ( L, -1 ); printf( "B = %s\n", str_value ); str_value = lua_tolstring( L, 2, &len_value ); // <--- (5) printf( "B = %s length = %d\n", str_value, len_value ); lua_settop( L, 0 ); // <--- (6) lua_close(L); printf( "sample end\n" ); return 0; }
5 소스 설명
(1) 루아 스크립트에서 선언되어 있는 A 변수를 사용하기 위해서 스택으로 이동시킵니다.
(2) 루아 스크립트에서 선언되어 있는 B 변수를 사용하기 위해서 스택으로 이동시킵니다.
(1) 과 (2) 과정을 거치면 다음과 같이 루아 값이 스택으로 옮겨 집니다.
| |
+------------------+
2 | B | -1
+------------------+
1 | A | -2
+------------------+
(3) 스택의 1 번 위치와 -2 는 위 스택구조로 보면 동일한 위치를
가리키고 해당 위치에 있는 값이 어떤 값이든 상관없이
정수로 바꾸어 옵니다.
(4) 스택의 2 번 위치와 -1 는 위 스택구조로 보면 동일한 위치를
가리키고 해당 위치에 있는 값이 어떤 값이든 상관없이
문자열로 얻어 옵니다.
(5) 스택에 있는 값을 문자열로 변환해서 얻어 올 때
문자열에 길이까지 알고 싶다면 lua_tolstring() 함수를
사용해야 합니다.
(6) 더 이상 참조하지 않으면 스택으로 복사된 내용을 모두 제거 합니다.
6. 결론
루아 스크립트에 선언된 변수를 얻어 올때는
1) lua_getglobal() 함수를 이용하여 스택으로 값을 복사합니다.
2) lua_toXXX() 계열의 함수를 이용하여 C 에서 사용할수 있는
변수로 변환 합니다.
꼭 기억 할것은 C에서 참조하려면 스택에 해당 값이 루아에서
복사해 와야 하고
스택에서 제거되면 해당 참조나 변환이 불가능합니다.
그러므로 스택에서 값을 가져온후 스택에 내용을 제거한 후에도
계속 참조하려면
C 에 따로 버퍼나 변수값을 만들고 복사해서 사용해야 합니다.
7 수행 예
다음은 보드에서 수행한 예 입니다.
[root@falinux nfs]$ ./app_run_lua
sample : C function call Lua Script
ENTER RUN.LUA
BEGIN.........
A = 1234
B = Hey
END.........
Enter C routine
A = 1234
A = 1234
B = Hey
B = Hey
B = Hey length = 3
sample end
[root@falinux nfs]$