문제

좋아, 그래서 나는 SWIG를 사용하여 LUA에 노출되는 C ++ 클래스가 있습니다. 스크립트는 객체를 생성하지만 관리자 클래스에는 객체에 대한 포인터가 있으므로 어떤 이유로 든 C ++ (또는 다른 스크립트)로 수정할 수 있습니다.

문제는 스크립트가 객체를 완성하면 GC 메타 메드를 구현하지 않고 쓰레기 수집기가 수집하는 것을 어떻게 제어 할 수 있다는 것입니다.

예는 다음과 같습니다.

--Script that creates the object
someObject = Utils.Object("Obj name");

이제 객체가 관리자에게 등록되어 나머지 응용 프로그램 (및 기타 스크립트)이 액세스 할 수 있습니다.

--Another script
obj = ObjManager:GetObject(0);

분명히 현실적인 예는 아니지만 내 질문을 보여줍니다. C ++의 GC 메타 메드없이 쓰레기 수집기를 거부 할 수있는 방법이 있습니까?

관리자가 C ++이며 Utils는 노출 된 클래스를 수용하는 모듈 이름입니다. 또한 객체는 생성자의 관리자에게 자체적으로 등록됩니다.

미리 감사드립니다.

도움이 되었습니까?

해결책

LUA의 GC는 LUA 내에서 보유한 참조에 대해서만 알고 있으며, 이는 합리적인 구현 제약 조건입니다. 이것은 물체의 수명이 Lua의 통제하에 있음을 의미합니다. 하나의 스크립트 또는 함수를 실행하여 생성 된 객체를 나중에 스크립트 또는 함수에 사용할 수 있어야하는 경우, GC가되도록 LUA 상태 내에서 이에 대한 참조를 보존해야합니다. 알고 있습니다 여전히 사용 중입니다. 그렇지 않으면 쓰레기와 구별 할 수 없으며 언제든지 버릴 수 있습니다.

이것은 LUA 레지스트리 테이블의 목적 중 하나입니다. C 측은 LUA 객체를 레지스트리 테이블에 배치하여 모든 LUA 객체에 대한 참조를 쉽게 참조 할 수 있습니다. 키는 C 라이브러리에 알려진 고유 한 값일 수 있습니다 (주소 주소 static 가벼운 userData로 변환 된 변수는 종종 다른 라이브러리의 키와 충돌 할 수 없기 때문에 종종 좋은 선택입니다). 또는 함수 호출 luaL_ref(L, LUA_REGISTRYINDEX) 스택 상단에 레지스트리 테이블에 항목을 놓고 고유 한 정수 키를 반환합니다. 이것은 GC로부터 함수를 보호하고 "포인터"(정수 키)를 C 구조에 저장하여 검색하고 호출 할 수 있도록 스크립트로 제공 된 콜백 함수를 저장하는 데 적합합니다. 나중에.

주목하십시오 luaL_ref() 모든 테이블에서 참조를 관리하는 데 사용할 수 있으므로 글로벌 레지스트리 테이블이 아닌 목적을 위해 모듈에 비공개 인 테이블을 사용하는 것이 좋습니다. 이 경우 테이블 ObjManager 그 자체는 좋은 후보자 일 수 있습니다.

다른 팁

예; utils.를 개인 테이블에 객체를 흡수하십시오. 그러면 그럴 것입니다 절대 수집되지만 게임을 재생할 수 있습니다 (테스트되지 않음) :

do
  local retained = { }  -- table forces objects to be retained
  local old_util_object = Util.Object
  Util.Object = function(...)
    local obj = old_util_object(...)
    retained[obj] = true
    return obj
  end
  Util.Free = function(obj)
    assert(retained[obj])
    retained[obj] = nil  -- now obj can be garbage-collected
  end
end

C ++ 측에서 동일한 문제를 해결하려면 C ++ 코드에 개인 테이블을 할당하여 LUA 레지스트리에 넣으십시오. 그런 다음 LUA 소스 대신 C API 만 사용하여 동일한 삽입/삭제 게임을 재생할 수 있습니다. LUA의 C API에 익숙하다고 가정하면 간단합니다. 전에 C API를 사용하지 않았다면 학습을 시작하기에 더 좋은 시간은 없습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top