블로그는 나의 힘!
[ Programing ]/Lua Scirpt2022. 3. 6. 01:08

앞의 정리 08. C++과 연동에서 연동에 필요한 기본적인 것들에 대해서 알아 보았습니다.
지금의 예제는 제한된 기능의 루아 콘솔 프로그램 입니다.

GAME DEVELOPMENT with LUA에서 처음으로 나오는 연동 예제 입니다.

 

실력이 모자란 관게로 처음 이 예제를 봤을 때 이게 뭐고 라고 생각했습니다.
그래도 여러번 보게 되니깐 대충은 이해가 가더라고염 ~.~;;

일단 전체 소스 코드를 먼저 올리고 그 후 각 부분에 대해서 설명 하겠습니다.

 

=======  제한된 루아 콘솔 프로그램 =======

// 시스템 헤더 포함
#include <stdio.h>
#include <string.h>

/*
** 루아 헤더 포한
** 루아 헤더들은 C로 되어 있다. 그런데 이것은 C++ 프로그램이기 때문에,
** 루아 헤더들에 담긴 정의들이 C로 굍 것이고 따라서 C++ 이름 섞기를
** 적용하지 말아야 한다는 점을 C++ 컴파일러에게 알려 주어야 한다.
** extern "C"가 바로 그런 의미이다.
*/
extern "C" {
     #include <lua.h>
     #include <lualib.h>
     #include <lauxlib.h>
}

/*
** 루아글루 함수의 예이다.
** 이 함수는 루아에서 호출 한다.
** 루아는 ANSI C로 작성된 것이므로, 앞에서와 마찬가지로
** extern "C"를 지정해서 C++ 이름 섞기를 방지 한다.
*/
extern "C" int _Version(lua_State *L)
{
     puts("This is Version 1.0 of the Console Program");
     puts(LUA_VERSION);
     puts(LUA_COPYRIGHT);
     puts(LUA_AUTHORS);
     return 0;
}

/*
** 루아 환경에 등록할 루아글루 함수들의 정보
** 이후 루아 API를 이용해서 이들을
** 실제로 루아 환경에 등록한다.
*/
static luaL_reg ConsoleGlue[] =
{
     {"Version",  _Version},
     {NULL, NULL}
};

char gpCommandBuffer[254];

const char *GetCommand(void)
{
     printf("Ready> ");
     return gets(gpCommandBuffer);
     puts("\n");
}

void main(void)
{
     puts("Lua Console (basic) (c) 2004 Charles River Media");
     puts("Enter Lua commands at the prompt, [QUIT] to exit\n\n");

     // 루아 환경 생성 및 설정
     lua_State *pLuaState = lua_open();
     luaopen_base(pLuaState);
     luaopen_io(pLuaState);
     luaopen_string(pLuaState);
     luaopen_math(pLuaState);
     luaopen_debug(pLuaState);
     luaopen_table(pLuaState);

     // 루아 글루 함수 등록
     for(int i=0; ConsoleGlue[i].name; i++)
     {
           lua_register(pLuaState, ConsoleGlue[i].name, ConsoleGlue[i].func);
     }

     // 명령 처리
     const char *pCommand = GetCommand();
     while(stricmp(pCommand, "QUIT") != 0)
     {
          // 문자열을 루아 환경에 적재, 구문 점검, 실행가능 형태로 준비
          if (luaL_loadbuffer(pLuaState, pCommand, strlen(pCommand), NULL) == 0)
     { 
          // 실행 가능 상태이면 실행
          if(lua_pcall(pLuaState, 0, LUA_MULTRET, 0) != 0)
          {
               // 명령 실행 실패
               printf("ERROR:%s\n", luaL_checkstring(pLuaState, -1));
          }
     }
     else
     {
          // 명령 읽기 실패
          printf("ERROR:%s\n", luaL_checkstring(pLuaState, -1));
     }
          // 다음 명령 가져 오기
         pCommand = GetCommand();
     }
     lua_close(pLuaState);
}

 

※ 색상의 구분이 안되어서 불편 하군요~ 그래도 일일이 다하기는 귀찮고해서 그냥 주석 부분만 처리 했습니다.

 

=======  예제에 대한 설명 =======

1. 시스템 헤더 포함 

이 부분은 설명 하지 않겠습니다. 필요한 헤더 파일을 추가 하면 되겠지요~~

 

2. 루아 헤더 포함

루아 API에 관련된 함수들의 헤더 파일 입니다. 각각의 헤더 파일의 자세한 기능은 아직 저도 모릅니다.

나중에 알게 되면 변경 하도록 하고 
여기서 중요한건 주석에도 나와 있는 C++ 이름 섞기 방지를 해야 한다는 것 입니다.

 

3. 루아 글루 함수

루아 글루 함수의 의미는 앞에서도 설명 했기 때문에 생략하도록 하고요. 
지금의 루아 글루 함수 int _Version( lua_State* L) { } 함수는 단순한 루아 버전 정보를 출력하는 함수 입니다.

이 함수를 호출하는 부분은 이 예제 소스에는 나와 있지 않습니다만,
예제가 콘솔 프로그램 이기 때문에 출력 해보는 것은 어렵지 않습니다.
우선 루아 스크립트 파일을 하나 만듭니다.

파일명을 D:\\lua_scr\\console_test.lua로 만들고, 
안의 내용을 Version()으로 만든 후에 최종적으로 루아 콘솔 프로그램 예제를 실행 시킨 후 

Ready > dofile("D:\\lua_scr\\console_test.lua")  ↙
하면 루아 글루 함수 _Version() 이 호출되어 루아 버전 정보를 화면에 출력 하게 된다.

 

4. 루아 환경 등록을 위한 정보 관리

lua_reg 변수 안에 { "lua_name", C++_name } 쌍으로 들어가게 된다.

C++_name이 실제로 C++에서 작성한 루아 글루 함수의 이름이고, 
"lua_name"은 루아 스크립트 환경에서 루아 글루 함수를 호출 할때 사용 되는 이름 입니다.

 

5. 명령을 받는 일반 함수

C++ 상에 gets()함수를 이용하여 입력한 문자열을 gpCommandBuffer에 담은 다음 반환 하는 함수.

이 함수 반환하는 gpCommandBuffer에 루아 스크립트 명령(청크)가 들어가게 되면, 
루아 API로 이를 분석하여 처리 하게 된다.

 

6. 루아 환경 생성 및 설정

루아 환경은 lua_open()으로 생성하며, 이 함수가 반환값을 이용하여 루아 환경을 설정하게 된다.
필요한 부분만 설정 하면 된다.

 

7. 루아 글루 함수 등록

루아 글루 함수는 lua_register()로 등록 된다.
인자로 '루아 환경 변수', '스크립트에서의 이름',' C++에서의 함수'를 받는다.

 

8. 명령 처리 부분

명령 처리 부분에서는 루아 API를 이용하여 C++에서 루아 스크립트(루아 함수)를 사용할 수 있게 한다.

이 예제 프로그램이 루아 콘솔 프로그램 이므로 우리가 입력한 명령들을 루아 환경에 적재하고 
적합한 구문 인지를 점검하여 실행 가능한 형태로 바꾸는 함수가 lua_loadbuffer()이다.

여기에 들어가는 인자 중 pCommand가 루아 스크립트에서 작성한 함수라 그 함수의 적합성을 판단하여
실행가능한 형태로 만든 것이다. 
(이 프로그램에서 실행 가능한 형태가 되기 위해서는 이전에 
 dofile로 먼저 해당 함수를 포함한 루아 스크립트 파일을 호출하는것이 필요 할 것이다.)

그리고 그것을 실제로 실행하는 기능을 하는 함수가 lua_pcall() 함수 이다.
lua_pcall()함수가 루아 스택에서 해당 명령을 가져와서 실행을 하게 된다.

실행 여부가 만약 실패하게 되면, 오류 메시지를 남기는데 이 메시지 출력 하는 함수가 luaL_checkstring()함수 이다.

 

9. 루아 환경 해제

루아 환경을 생성 했으면, 필요 없을 시에는 lua_close() 함수로 해제 한다.

 

※ 설명 중간 중간 제가 추측하여 정리한 부분이 있어서 설명이 틀릴수 있을 지도 모르겠네요~
   이부분 양해 바랍니다.

    제가 실제로 해본 부분은 현재 여기까지 입니다.
    이 후로 실제로 루아 스크립트 내부의 함수를 C++에서 호출하고 그 반환값을 활용하는 방법과
    루아 글루 함수를 루아 스크립트 내부에서 호출하고 그 반환값을 활용하는 방법에 대해 학습을 하고
    정리해서 올릴까 합니다. ^^*

 



[출처] Lua - 09. 간단한 예제|작성자 악마



 

Posted by Mister_Q