--[[

루아글루 함수

루아글루 함수는 루아 스크립트에서 직접 호출할수 있는 형태로 작성된C++ 함수이다. 루아 스크립트에서 C++ 코드로의 통신에서 가장 주된 수단이 루아글루 함수이다.

루아 스크립트에서 C++로 작성된 함수가 필요할 때에는 루아글루 함수를 호출한다.

루아 프로그래머가 볼때에는 루아글루 함수와 루아 안에서 정의한 함수 사이에 아무차이가 없다.

이런 사실 덕분에, 필요한 함수를 일단 루아로 만들어서 사용하고 나중에 그 함수가 성능상의 병목임이 밝혀지면 C++로 이식하는 유용한 접근방식을 취할 수 있다.

진짜 루아 함수나 루아글루 함수나 루아 스크립트안에서 호출하는 방식은 정확히 동일 하므로, 원래의 진짜 루아 함수를 제거하고 (또는 이름을 바꾸고) 루아글루 함수로 대체한다고 해도 그함수를 사용하던 루아 스크립트는 변경할 필요가 없다.

루아글루 함수는 AddFunction메서드로 등록한다.(잠시 후에 예가 나온다.) LuaGlue라는 형식은 루아글루 함수의 서명을 간단하게 만들고 C++과의 연동 상의 문제점을 숨기기위한 사용자 정의 형식이다.

 

루아글루 함수: 매개변수와 반환값

루아글루 함수가 유용하게 쓰이려면, 루아 스크립트에서 함수에 전달한 매개변수들을 루아글루 함수에서 가져올 수 있어야 한다.  루아는 루아 스택을 통해서 매개변수들을 전달한다.  루아글루 함수의 매개변수 형식은 루아가 지원하는 어떠한 자료 형식이라도 가능하다.  루아의 모든 수치들은 C++에서 double이 되며, 문자열은 널 종료 문자열이 된다.   루아의 테이블 역시 함수의 인수가 될 수 있지만, 루아 API로 테이블을 다루는 것은 매우 번거로우며 곡 필요한 것도 아니다. 또한 루아는 사용자 자료라는 자료형식을 지원하며 이 형식 역시 루아글루 함수의 매개변수로 전달될 수 있지만, 이책에서는 다루지 않겠다.

cLua에는 루아글루 함수안에서 매개변수를 얻는데 사용할 수 있는 몇가지 메서드들이 있다. cLua::GetStringArgument는 문자열 인수에 해당하는 널 종료 문자열의 포인터를 돌려준다. 만일 주어진 인수가 문자열이 아니거나 어떤 문제가 있었다면 NULL을 돌려준다. cLua::GetNumberArgument는 double 형식의 수치 인수 값을 돌려주되, 문제가 있었다면 0.0을 돌려준다.  두 메서드 모두, 루아 스택에서 가져올 매개변수의 번호를 지정하는 매개변수를 받는다. 매개변수 번호는 호출문의 매개변수들에서 제일 왼쪽 매개변수가 1이고 오른쪽으로 가면서 1씩증가한다.

반환값 역시 루아 스택을 거친다. 반환값을 돌려주는 방식은 간단하다. 호출자에게 돌려줄 값을 루아 스택에 쌓고, 그 개수를 C++ return 문을 통해서 루아에게 알려주면 된다. C++함수가 루아 환경에게 반환값 개수를 돌려주는 이유는, 루아에서 하나의 함수가 여러개의 반환값들을 돌려줄 수있기때문이다.  이러한 다중 반환값은 매우 유용하게 쓰이며 루아글루 함수에도 적용된다.  반환값 개수와 루아 스택에 쌓은 값들의 개수는 일치해야 한다. 루아 스택에 값을 쌓을때 사용하는  cLua 메서드는 cLua::PushString과 cLua::PushNumber이다.

아래에 루아 글루 함수의 예가 나와있다. 이 예에서 보듯이 매개변수 번호에 해당하는 지역 변수를 1로 초기화하고, 각 매개 변수를 가져올때마다 후증가시키면 매개변수 번호가 잘못될 위험이 없다.

그리고 함수 처리 결과에 따라 의미 있는 반환값개수가 달라진다고 하더라도, 기본값들을 채워서라도 항상 같은 개수의 반환값들을 돌려 주는것이 좋다. 루아에서 nil에 접근하면 오류가 발생하기 때문이다.  오류처리에 대해서는 나중에 다시 이야기 하겠다.

--]]

--루아글루 함수에서 매개변수들을 얻고 반환값을 돌려주는 예

extern cLua *pLua;

LuaGlue _SwapExt(lua_State *L)

{

  int argNum = 1;

  const char *fileName = pLua->getStringArgument(argNum++);

  const char *newExt =

     pLua->GetStringArgument(argNum++);

  char fname[_MAX_FNAME];

  char ext[_MAX_EXT];

  _splitpath(fileName, NULL, NULL, fname, ext);

  std::string sRet = fname;

  if(newExt[0] != '\0')

  {

     sRet += ".";

     sRet += newExt;

   }

  lua->PushString(sRet.c_str());

  return 1;

}

--[[

이 함수는 cLua::GetStringArgument 를 이용해서 루아 환경으로부터 두 개의 문자열 인수를 가져온다.(일단 C++로 넘어오면 그 문자열들은 널 종료 문자열이 된다.)그 문자열들로 약간의 조작을 한 후, 결과 문자열을 cLua::PushString 으로 루아 스택에 쌓고 1(반환값 개수)을 루아에게 돌려준다

 

요약

루아의 설계자들은 루아를 매우 유연하고 이식성 좋은 방식으로 C++ 프로그램에 통합 시킬수 있는 시스템을 만들어 두었다 이번 장에서는 여러 가지 예제들을 통해서 C++프로그램에 루아를 통합하는 방법을 살펴보았으며, 또 그러한 작업에 관련된 복잡하고 읽기 어려운 코드를 좀 더 읽기 쉽고 깔끔하게 만들어주는 C++ 클래스도 하나 소개했다.

--]]

안정적인 DNS서비스 DNSEver DNS server, DNS service
Posted by 키르히아이스

댓글을 달아 주세요