문제

SWIG는 학부모 클래스에 타입 객체를 사용할 수 있도록 다양한 기능을 제공합니다. 그러나 C ++에서는 다음과 같은 기능을 생성 할 수 있습니다.

A * getAnObject()
{
  if(someBoolean)
    return (A *) new B;
  else
    return (A *) new C;
}

여기서 "A"는 클래스 "B"및 "C"의 부모입니다. 그런 다음 포인터가 "B"유형 또는 "C"유형으로 반환 된 다음과 같은 편의성으로 반환 할 수 있습니다.

B * some_var = (B *) getAnObject();

포장지를 사용하여 스크립팅 언어로 런타임에서 일반 포인터 생산 기능에서받은 객체를 타입 캐스트 할 수있는 방법이 있습니까? (제 경우에는 LUA?) 약 100 개의 가능한 클래스 중 하나를 생성 할 수있는 기능이 있으며 C ++에서 유지해야 할 막대한 스위치 구조를 작성하지 않으려 고합니다. 제네릭 포인터를받는 지점에서는 캐스트하려는 데이터 유형의 문자열 표현도 있습니다.

이견있는 사람? 감사!

-- 편집하다 --

SWIG는 모든 클래스에 대한 사본 생성자를 생성하도록 제안합니다. 내가 그것들을 생성한다면, 나는 다음과 같은 것을 할 수 있습니까? :

var = myModule.getAnObject(); -- Function that returns an object type-cast down to a pointer of the parent class, as in the function getAnObject() above.
var = myModule.ClassThatExtendsBaseClass(var); -- A copy constructor that SWIG theoretically creates for me

그리고 var를 상속 클래스의 인스턴스가되도록 알고 있습니다 상속 클래스의 사례입니까?

도움이 되었습니까?

해결책

나는 내 문제에 대한 해결책을 개발했다. 나는 Lua의 쓰레기 수집을 처음 접했기 때문에 그것이 메모리 누출 방지인지 확실하지 않지만 필요한 작업을 수행합니다. (유효한 데이터 유형과 해당 데이터 유형으로 캐스트하지 말아야 할 객체를 전달하면 나쁜 점이 발생합니다.)

=================================================================================

static int lua_typecast_Object_I(lua_State *L)
{
        void * myDataPtr;
        void ** ptrToPtr = &myDataPtr;

        // Attempt to convert the first parameter to a pointer of
        // the lowest parent type from which all other data types 
        // inherit. e.g. "Object_I"

        if (!SWIG_IsOK(SWIG_ConvertPtr(L, 1, ptrToPtr, SWIGTYPE_p_Namespace1__Object_I, 0)))
        {
                lua_pushnumber(L, -1);
                lua_pushstring(L,"Pointer conversion in typecast function failed.");
                return 2;
        }

        const char * type_name = luaL_checkstring(L, 2);

        // Search the SWIG module for a swig_type_info that contains the data
        // type string that was passed as the second parameter

        swig_module_info* module=SWIG_GetModule(L);
        swig_type_info *type = SWIG_TypeQueryModule(module,module,type_name);
        if(type == NULL)
        {
                lua_pushnumber(L, -2);
                lua_pushstring(L,"Failed to find swig_type_info for specified type.");
                return 2;
        }

        // Using the swig_type_info that we found, create a new object on 
        // the stack of the desired data type and return.

        SWIG_Lua_NewPointerObj(L, myDataPtr, type, 0);
        return 1;
}

=================================================================================

그것이 누군가를 돕기를 바랍니다!

다른 팁

클래스 유형의 SWIG 구조 SWIG_TYPE_INFO를 보유하는 TypEMAP 및 클래스 필드를 사용하여 이것을 해결했습니다.

예를 들어. 기본 링크 된 목록 기능이 포함 된베이스 클래스가 있다고 가정하지만 실제 노드는베이스 클래스에서 파생 된 클래스 일 수 있습니다. 따라서 다형성 연결 목록이 있습니다. 기본 클래스 I에서 I는 Swig_Typequery (..)로 호출 한 결과를 보유하는 "stored_swig_info"값을 정의합니다. 초기화 중에이 값을 설정했습니다. 그런 다음 런타임에 다음을 사용할 수 있습니다.

// The typemap converts a function result from C->Lua. 
%typemap(out) BaseClass* {
   // stored_swig_info is set by calling SWIG_TypeQuery("DerivedClass *"), done at
   // initialization, so it can be used here to read the actual type
   swig_type_info* info = $1->stored_swig_info;
   SWIG_NewPointerObj(L, $1, info, 0); SWIG_arg++;
};

// base class
class BaseClass {
private:
  swig_type_info *stored_swig_info;
public:
  BaseClass* next () { ... };
  BaseClass* prev () { ... };
};

// derived class
class DerivedClass: public BaseClass {
};

실제 클래스 모듈에서 생성자는 다음을 수행합니다.

BaseClass::BaseClass () {
  ...
  stored_swig_info = SWIG_TypeQuery("BaseClass *");
  ...
}

...

DerivedClass::DerivedClass () {
  ...
  stored_swig_info = SWIG_TypeQuery("DerivedClass *");
  ...
}

구현에 대한 메모. LUA 모듈이 초기화 된 후이 초기화가 호출되거나 SWIG 타이프 타벨이 아직 채워지지 않은지 확인하십시오.

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