앞에 정리에서는 루아 글루 함수를 루아 스크립트에서 호출하고 그 반환값을 활용하는 방법에 관해서
예제로 알아 보았습니다.
이번에는 반대로 루아 스크립트의 함수를 C++에서 호출하고 그 반환값을 활용하는 방법에 관해서 예제를
통해서 알아 보고자 합니다.
C++에서 루아 함수를 호출하기 위해서는
해당 루아 함수가 있는 스크립트 파일이 로드되고 컴파일 과정까지를 마친 상태여야 된다.
그 후 해당 루아 함수에 필요한 인자 값을 넘겨야 하고, 해당 루아 함수를 호출하고 반환값을 받아서 처리 해야 된다.
======= 호출 과정 =======
1. 스크립트 파일을 로드하고, 컴파일 하는 과정에 관련된 함수는 앞에서 이미 봤던 함수들이다.
-- 스크립트 파일을 로드, 컴파일, 실행
int lua_dofile(lua_State* L, const char* filename);
-- 스크립트 파일을 로드, 커파일
int lua_loadfile(lua_State* L, const char*filename);
※ 실제로 아래 예제에서 lua_loadfile() 함수를 사용해보니 되지가 않던데 그에 관한 이유는 아직 모르겠네요~
혹시라도 아시는 분 있으시면 설명 부탁 드립니다. ^^*
2. 호출할 루아 함수 이름을 스택에 쌓는다.
void lua_getglobal(lua_State* L, const char* name);
3. 루아 함수에 필요한 인자 값을 넘겨 줄때는 스택에 해당 인자값들을 push 하면 됩니다.
-- 해당 인자값의 자료형에 맞게 스택에 push 하면 된다.
-- 한번에 하나씩 push하고, 스택에 구조에 맞게 push한다.
void lua_pushboolean(lua_State* L, int b);
void lua_pushinterger(lua_State* L, lua_Integer n);
void lua_pushnumber(lua_State* L, lua_Number n);
void lua_pushstring(lua_State* L, const char* s);
void lua_pushlstring(lua_State* L, const char* s);
const char* lua_pushfstring(lua_State* L, const char* fmt, ...);
4. 루아 함수에 필요한 인자값들을 모두 스택에 push 했으며, 해당 함수를 호출한다.
-- lua_getglobal()로 스택에 쌓아놓은 함수를 호출한다.
-- 스택에 올려 놓은 인자값의 개수와 루아 함수에서 반환할 반환값의 개수를 인자로 한다.
void lua_call(lua_State* L, int narg, int nresults);
======= C++에서 루아 함수 호출 예제 =======
예제는 "정리 10"에서 사용했던 예제를 수정하였습니다.
// 게임의 NPC 이름을 등록하고 삭제하는 프로그램을 루아와 연동하여 처리
// 시스템 헤더 포함
#include <iostream>
#include <list>
using namespace std;
// 루아 헤더 포함
extern "C" {
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
}
// NPC Name List
list<const char*> gpNPCName;
int gIndxNPC;
// NPC 이름을 찾아서 지우는 함수
int _FindDelNPC(const char* pName)
{
list<const char*>::iterator p = gpNPCName.begin();
while (p != gpNPCName.end())
{
if(0 == stricmp(*p, pName))
{
gpNPCName.erase(p);
return 0;
}
p++;
}
return -1; // 실패시
}
// 리스트에 NPC 이름을 등록
extern "C" int _addNPC(lua_State* pLuaState)
{
const char* pName = luaL_optstring(pLuaState, 1, 0);
gpNPCName.push_back(pName);
//printf("addNPC Name : %s\n",pName);
lua_pushstring(pLuaState, pName);
return 0;
}
// NPC 이름을 삭제 함수
extern "C" int _deleteNPC(lua_State* pLuaState)
{
int nChkIndx = -1;
const char* pName = luaL_optstring(pLuaState, 1, 0);
nChkIndx = _FindDelNPC(pName);
if(-1 == nChkIndx)
{
printf("Can't find Name : %s\n", pName);
return 0;
}
//printf("deleteNPC Name : %s\n", pName);
lua_pushstring(pLuaState, pName);
return 0;
}
// 현재 NPC들을 출력 하는 함수
extern "C" int _ViewNPC(lua_State* pLuaState)
{
int i = 0;
list<const char*>::iterator p = gpNPCName.begin();
while (p != gpNPCName.end())
{
i++;
//cout << "Now NPC : " << *p << endl;
lua_pushstring(pLuaState, *p);
p++;
}
return i;
}
// 루아글루 함수 등록을 위한 배열
static luaL_reg LuaGlue[] =
{
{"addNPC", _addNPC},
{"deleteNPC", _deleteNPC},
{"ViewNPC", _ViewNPC},
{NULL, NULL}
};
int 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; LuaGlue[i].name; i++)
{
lua_register(pLuaState, LuaGlue[i].name, LuaGlue[i].func);
}
lua_dofile(pLuaState, "D:\\lua_scr\\luaNPC.lua");
// luaL_loadfile(pLuaState, "D:\\lua_scr\\luaNPC.lua");
// lua_pcall(pLuaState, 0, LUA_MULTRET, 0); //! LUA_MULTRET == -1
lua_getglobal(pLuaState, "TestFunc");
lua_pushnumber(pLuaState, 1);
lua_call(pLuaState, 1, 1);
printf("Lua return value : %s\n", (const char*)lua_tostring(pLuaState, -1));
lua_close(pLuaState);
return 0;
}
======= 루아 스크립트 소스 =======
-- New C functions exposed to lua
-- addNPC("NPC Name")
-- deleteNPC("NPC Name")
print("Simple Lua Program!!")
npcName = addNPC("Joe")
print("Add NPC Name : ", npcName)
npcName = addNPC("Sue")
print("Add NPC Name : ", npcName)
npcName = addNPC("Kan")
print("Add NPC Name : ", npcName)
npcName = addNPC("Babo")
print("Add NPC Name : ", npcName)
npcName = deleteNPC("Sue")
print("Dell NPC Name : ", npcName)
npc1, npc2, npc3 = ViewNPC()
print("Now NPC : ", npc1, npc2, npc3)
print("\nLua Func TestFunc\n")
function TestFunc(npcCnt)
local npc
if npcCnt == 1 then
print("First NPC Name\n")
npc = npc1
elseif npcCnt == 2 then
print("Second NPC Name\n")
npc = npc2
else
print("Else NPC Name\n")
npc = npc3
end
return npc
end
※ 소스 설명은 앞의 정리들의 내용과 많이 중복 되는 부분이라서 생략하였습니다.
혹시라도 궁금한점 있다면 글 남겨 주세요~
======= 실행 결과 =======
......
[출처] Lua - 11. 루아 스크립트 함수를 C++에서 호출하여 활용|작성자 악마
'[ Programing ] > Lua Scirpt' 카테고리의 다른 글
[Lua] 매주 이벤트(퀘스트) 주차 초기화 계산. (0) | 2022.04.21 |
---|---|
[Lua] 날짜와 시간 함수. (0) | 2022.04.11 |
Lua - 루아 글루 함수를 루아 스크립트에서 활용 (0) | 2022.03.06 |
Lua - C++ 연동 간단한 예제 (0) | 2022.03.06 |
Lua - C++과의 연동 (0) | 2022.03.06 |