C000_lua.gif

 

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]$