
1. 개요
이 문서는 ARM 보드에서 동작하는 루아 스크립트에서 C 함수를 호출하는 방법을 기술 합니다.
루아 스크립트에서 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/090_lua_c_call
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" ); sum = c_sum( 3, 4 ); print( "3 + 4 = ", sum ); sum_str = c_str_sum( "I love " , "you" ); print( "string sum = ", sum_str ); 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 c_sum( lua_State *L ) { int a; int b; a = luaL_checkinteger( L, 1); // <<-- (6) b = luaL_checkinteger( L, 2); // <<-- (7) lua_pushinteger( L, a + b ); // <<-- (8) return 1; } int c_str_sum( lua_State *L ) { char *a_str; int a_len; char *b_str; int b_len; char sum_str[128]; a_str = luaL_checklstring( L, 1 , &a_len ); // <<-- (9) b_str = luaL_checklstring( L, 2 , &b_len ); // <<-- (10) memset( sum_str, 0, sizeof( sum_str ) ); strcat( sum_str, a_str ); strcat( sum_str, b_str ); lua_pushstring( L, sum_str ); // <<-- (11) return 1; } int main( int argc, char **argv ) { lua_State *L = NULL; int error; int save_index; printf( "sample : call c function from lua\n" ); L = luaL_newstate(); luaL_openlibs(L); lua_pushcfunction(L,c_sum ); // <<-- (1) lua_setglobal(L, "c_sum" ); // <<-- (2) lua_pushcfunction(L,c_str_sum ); // <<-- (3) lua_setglobal(L, "c_str_sum" ); // <<-- (4) error = luaL_loadfile( L, LUA_FILENAME ) // <<-- (5) || lua_pcall ( L, 0,0,0 ); printf( "Enter C routine\n" ); if( error ) { printf( "%s\n", lua_tostring(L,-1)); lua_pop(L,1); exit(0); } lua_close(L); printf( "sample end\n" ); return 0; }
5 소스 설명
(1)(2) 루아 스크립트에서 c_sum() 함수를 호출할수 있도록 등록합니다.
(3)(4) 루아 스크립트에서 c_str_sum() 함수를 호출할수 있도록 등록합니다.
(5) 루아 스크립트를 호출하여 실행합니다.
(6) 루아 스크립트에서 전달된 첫번째 파라메터가 정수형인가를 확인하고
이상이 있으면 프로그램을 중지합니다.
정상이면 정수값을 반환합니다.
(7) 루아 스크립트에서 전달된 두번째 파라메터가 정수형인가를 확인하고
이상이 있으면 프로그램을 중지합니다.
정상이면 정수값을 반환합니다.
(8) 두개의 정수를 합한후 스택에 넣습니다.
반환값의 갯수는 return 값으로 표현한다.
(9) 루아 스크립트에서 전달된 첫번째 파라메터가 문자열인가를 확인하고
이상이 있으면 프로그램을 중지합니다.
정상이면 문자열 선두 주소와 길이를 반환합니다.
(10) 루아 스크립트에서 전달된 두번째 파라메터가 문자열인가를 확인하고
이상이 있으면 프로그램을 중지합니다.
정상이면 문자열 선두 주소와 길이를 반환합니다.
(11) 합쳐진 문자열을 스택에 넣어 반환값으로 반환합니다.
반환값의 갯수는 return 값으로 표현한다.
7 수행 예
다음은 보드에서 수행한 예 입니다.
[root@falinux nfs]$ ./app_run_lua
sample : call c function from lua
ENTER RUN.LUA
3 + 4 = 7
string sum = I love you
END.........
Enter C routine
sample end
[root@falinux nfs]$