루아팅커 사용중에 이런경우는 어떻게 해결해야 하나요?

프로그래밍 일반에 관한 포럼입니다.

Moderator: 류광

Locked
킬제덴
Posts: 11
Joined: 2009-10-14 18:30

루아팅커 사용중에 이런경우는 어떻게 해결해야 하나요?

Post by 킬제덴 »

안녕하세요. 아래 yield, resume 질문했던 비회원입니다.
한가지 더 문제가 생겨서 질문 올립니다.

순수루아로 구현한 lua에서의 C함수 호출반환값과 팅커로 호출 반환한 값의 호환?문제입니다.
설명하기 쉽게 간단한 코드를 직접 써보겠습니다.

Code: Select all

--Lua코드. ctestobj는 CTest class형.
function Sample()
{
  data = ctestobj:Get()
  ctestobj:Set( data )      -- 팅커함수에서 받은 포인터값를 팅커함수로 넘겨준것
  C_Set( data )               -- 팅커함수에서 받은 포인터값을 일반C함수로 넘겨준것(팅커X순수루아)
}
라는 lua코드가 있을때...

// cpp쪽 구현은 다음과 같습니다.
class CTest;
extern CTest  g_data;
class CTest
{
public:
  CTest() {}
  ~CTest() {}
  CTest* Get( void )
  {
     return &g_data;
  }
  void Set( CTest *pData1 )
  {
     // 이때의 pData1
  }
};

CTest  g_var1, g_data;

int C_Set( lua_State *L )
{
  CTest *pData2 = lua_touserdata( L, 1 );          
  // 이때의 pData2
  return 0;
}
Set()은 팅커로 호출되는 cpp함수고요..
C_Set()은 순수루아로 호출되는 c함수입니다.
이때 lua에선 같은 data를 넘겨주는데...
Set()에서 받는 pData1과 C_Set()에서 받는 pData2가 서로다르더군요.
이경우는 Set()에서 받는값만 정상적으로 들어오고 C_Set()에서 받는건 이상한값이 들어있습니다.
규칙을 보아하니 팅커로 호출해서 받은 값은 팅커로 호출되는 함수에만 넘겨야 정상적으로 들어가고요
반대로 순수루아함수로 호출해서 받은값은 순수루아에서 받을때만 정상적으로 받아집니다.
이런경우는 어떻게 해결해야 하는지요. 두방식을 섞어쓰면 안되는건지요?
zupet
Posts: 2764
Joined: 2003-05-13 03:34
Location: NCSOFT LE팀

Post by zupet »

안녕하세요. 매크로 없는 메비~랍니다.

이 부분은 call by value, call by reference 를 둘다 구현하다가 생긴 문제입니다. 자세히 설명하자면 루아 팅커는 함수를 호출할때 객체를 '복사' 해서 넘기는 것과 '포인터' '참조' 를 다 지원합니다. 루아 내에서는 세가지를 모두 동일하게 '객체'로 취급하고 있지만 C++ <-> Lua 경계를 넘나들때는 세가지가 나름 잘 구분되고 있습니다. C++ 쪽에서 잘 구분해주지 않으면 싫어하니까요. ^_^

문제는 '값'으로 넘어갈때 소멸자가 호출되지 않는다는 것입니다. 그래서 루아 팅커에서는 이러한 객체를 감사는 wrapper 3가지 val2user, ptr2user, ref2user 를 만들어서 Lua 로 넘어가는 객체를 감싸고 있습니다. 따라서 Lua 에서 루아 팅커가 넘긴 포인터를 보면 실제 객체의 포인터가 아니라 객체를 감싸는 ptr2user 각체의 포인터가 나오게 되는 것입니다.

Lua가 혹여나 다음 버젼에서 lus_islightuserdata() 함수가 추가된다면 이 모든 문제들이 깔끔히 해결될 것 같습니다. 지금 생각해봤는데 메타테이블을 두가지 타잎으로 만들어서 소멸자 호출 여부를 결정해주는 방법도 나름 괜찮을 것 같습니다. (고쳐서 0.6 버젼이나 내놔볼까..)
Locked