2014-12-25 4 views
0

최근에 상황에 대해 설명하고 싶습니다. 질문을하기 위해 상황을 설명하고 싶습니다.기지를 정해지지 않은 크기의 객체로 설정하십시오.

저는 파이썬 C++ 래퍼를 작성하고 있습니다. Python의 기본 단위는 PyObject입니다. Python의 모든 엔티티는 PyObject + 더 많은 옵션 항목입니다.

즉, 첫 번째 sizeofPyObject) 바이트는 PyObject의 필드를 채우는 것이 보장되지만 다양한 객체는 연속적인 추가 메모리를 할당 할 수 있습니다.

이점 (이유?)은 무엇이든 의미있는 PyObject으로 다시 유형 변환 될 수 있다는 것입니다.

class CxxWrapper : PyObject {} 

가 나는 void foo(PyObject* p)을 만들 말, 그리고 파이썬 런타임의 함수 포인터 테이블 중 하나에 foo를 삽입 : 나는 시도하고있어

는 짐승을 포장합니다.

그런 다음 런타임은 관련 함수 (PyObject)에 대한 포인터를 전달하는이 함수를 (어떤 이유로 든) 트리거합니다.

나는 곧장 해당 CxxWrapper 객체에이 캐스트 할 수 있도록하고 싶습니다 :

CxxWrapper* cxxw = static_cast<CxxWrapper>p; 

그러나,이 메커니즘이 작동하도록 할 수있는 방법을 볼 수 없습니다. 기본 객체를 어떤 값으로 설정하는 방법이 보이지 않기 때문에 PyObjectPlusExtra.

이렇게 할 방법이 있습니까? 그렇다면 C++의 한계점은 무엇입니까?

+0

당신은 확실히 다음 기본 클래스 또는 첫 번째 멤버가의 PyObject로되어있는 몇 가지 클래스를 선언 할 수 있습니다 다른 회원이 따라옵니다. –

+0

'CxxWrapper * cxxw = static_cast (p); ' –

+0

@JonathanPotter하지만 CxxWrapper의 자체 생성자는 파생 된 개체를 생성 할 기회를 얻지 못합니다. –

답변

0

틀린 질문입니다. 20시 20분 돌이켜 보면, 여기에 무슨 일이 일어나고 있는지의 :

나는 C 라이브러리를 처리하고있어이 C 스타일의 상속 방식을 사용, 즉

struct CBase{ 
    int a,b; 
} 

struct CDer{ 
    CBase ab; 
    int c; 
} 

내 C를 계획하고있어 ++ 코드를 따라서 :

class CxxBase : CBase 

그래서 C에서 포인터를 가져 오면 해당 CxxBase 객체로 변형 할 수 있고 그 반대의 경우도 가능합니다.

문제는 C++에서 상속을 C 예제와 거의 동일하게 관리한다는 것입니다. Final : Der : Base는 Base를 저장 한 다음 Der를 저장 한 다음 Final 객체를 인접한 메모리에 저장합니다.

그래서이 조합을 수행하는 것은 불가능합니다. CDer와 CxxDer는 알 수없는 크기입니다.

배리 (Barry)가 제안한 매핑과 같은 다른 기술이 필요합니다.

그러나 상당히 비싼 조회가 필요합니다.

내가 일하고 있어요 프로젝트에서 기존보다 더 나은 솔루션을 볼 수 있습니다

:

struct Bridge { 
    CObj cob; 
    CxxObj* p_cxxob; 
} 

const CxxObj& to_cxx(CObj* cob) { return *(cob->p_cxxob); } 
1

개체를 구성 할 수 없으므로 잘못된 방법입니다.

넣어 당신이 여분의 수업 시간에 원하는대로 당신이 갈 수 있습니다 : 당신이 대신 할 수있는 것은 PyObject의와 객체 사이의 맵을 정의합니다.

+0

C++ 11 태그를 찾지 못했습니다. – Barry

+0

감사합니다. 나는이 접근법을 고려하지 않았습니다. 그것은 typecasting base-> 파생 된 비용이 무엇인지 모르겠지만 비용이 많이 드는 것처럼 보입니다. –

+0

캐스트의 비용은 0이지만, 파생 된 오브젝트가 없으므로별로 중요하지 않습니다. – Barry