2013-03-06 3 views
1

I 파이썬 측에서 생성 된 swig wrapped 객체와 C++ 측에서 생성 된 wrapped 객체에 관해 질문이 있습니다. 그때 할 경우Swig와 Python - 다른 객체 인스턴스

import engine 
sphere_0 = engine.Sphere() 
container = engine.Container() 
container.add() 
sphere_1 = container.get(0) 

그리고 파이썬에서 랩의 첫 번째 인스턴스를 다음

%module engine 
%{ 
#define SWIG_FILE_WITH_INIT 
#include "sphere.h" 
%} 

// ------------------------------------------------------------------------- 
// Header files that should be parsed by SWIG 
// ------------------------------------------------------------------------- 
%feature("pythonprepend") Sphere::Sphere() %{ 
    print 'Hello' 
%} 
%include "sphere.h" 

나는 다음과 같은 간단한 C++ 클래스 정의

#include <vector> 

class Sphere 
{ 
public: 
    Sphere(){}; 
}; 

class Container 
{ 
public: 
    Container() : data_(0) {}; 

    void add() { 
     data_.push_back(Sphere()); 
    } 

    Sphere & get(int i) { return data_[i]; } 

    std::vector<Sphere> data_; 
}; 

다음과 같은 꿀꺽 꿀꺽 설정을 가지고 가정 Sphere 클래스는 init 파이썬 배치 인터페이스 ('Hello'가 인쇄 됨) 메소드를 호출합니다.

그러나 인스턴스가 C++ 측에서 생성되는 두 번째 인스턴스 ('Hello'가 인쇄되지 않음)는 없습니다.

내 목표는 구성시 오브젝트에 파이썬 기능을 추가 할 수 있기 때문에, 위의 두 인스턴스화 시나리오 모두에 대해 올바른 방법에 대한 지침이있는 사람이 있으면 알려 주시면 기쁩니다. .

안부,

MADS

+0

'sphere_1' (예제의 마지막 줄)을 구할 때 "hello"가 출력됩니까? – Dave

+0

아니요 - 인쇄되지 않습니다. 이것은 __init__가 호출되는지 확인하는 간단한 테스트 일뿐입니다. – repoman

답변

1

나는 보통 인터페이스 파일에 명시 적 pythoncode 블록이 같은 일을 수행

%pythoncode %{ 
def _special_python_member_function(self): 
    print "hello" 
    self.rotate() # some function of Sphere 
Sphere.new_functionality=_special_python_member_function 
%} 

그래서 당신이 클래스에 임의의 파이썬 기능에 추가 할 수 있습니다 SWIG 인터페이스가 제공하는 것의 맨. rename의 C 기능을 일부 필요로 할 수도 있지만 필요합니다.이 모든 기능을 사용자에게 제공해야합니다. 원하는 기능.

나는 이러한 방식으로 __init__을 다시 매핑하려고 시도한 적이 없으므로 그 동작이 어떻게 될지 잘 모릅니다. 그것이 작동하지 않는다면, 파이썬 객체가 생성시 주어진 내부 상태 (멤버 변수)를 가질 수 없다.

def function_that_depends_on_python_specific_state(self, *args): 
    if not hasatttr(self, 'python_data'): 
     self.python_data = self.make_python_data() # construct the relevant data 
    pass # do work that involves the python specific data 

및 파이썬 특정 데이터의 존재를 확인 : 당신이 강제 될 것입니다 무엇

게으른 평가를 할 수 있습니다. 이 중 약간의 경우가 이라면, 위와 같은 함수에 넣을 것입니다. 그러나 그것이 지저분 해지면 __getattr__을 수정하여 파이썬 특정 데이터 에 액세스 할 때 해당 구성 요소를 구성 할 수 있습니다.

def _sphere_getattr(self, name): 
    if name=='python_data': 
     self.__dict__[name]=self.make_python_data() 
     return self.__dict__[name] 
    else: 
     raise AttributeError 
Sphere.__getattr__ = _sphere_getattr 

IMHO, 기본 C 구현에 독립적 인 새로운 기능의 많은 양을 제한, 데이터, 당신은 어떻게 내가 내 파이썬 구체 클래스는 하위가 될 수 있습니다 "물어 적용됩니다 C Sphere 클래스의 클래스는 같지만 같은 타입으로 유지 하시겠습니까? "

+0

데이브 : 고마워. 하위 클래스는 Python 측에서 객체를 생성하는 방법입니다. 그러나 Container 객체에서 get()을 호출하여 객체가 C++ 측에서 생성되면 더 어려워 보입니다.이 문제를 해결하기위한 제안이 있습니까? – repoman

+0

말 그대로 포함시키려는 동작에는 다음이 포함됩니다. 모든 인스턴스에 대해 인스턴스 생성시 무언가를 인쇄 하시겠습니까? 그렇다면 어떻게해야 할 지 모르겠다. 그게 네가 원하는 것의 일부가 아니기 때문에 네가하고 싶은 일을 더 자세하게 지정할 수있다. – Dave

+0

print 문은 __init__이 호출 된 경우에만 테스트에 추가되었습니다. 사실, 내가하고있는 일은 OpenGL 씬에서 액터를 다루기위한 상대적으로 복잡한 C++ 객체들의 모음입니다. 이 객체에 pure Python 기반 멤버를 추가 할 수 있기를 원합니다. 이것들은 Python 측에서 인스턴스화 될 때 문제가되지 않습니다. 왜냐하면 pythonprepend를 사용하여 이들을 추가 할 수 있기 때문입니다. 그러나 오브젝트가 다른 C++ 기반 오브젝트 (Container 클래스에서 add() 및 get()을 호출하여 생성 된 경우)는 무시됩니다. 즉, __init__이 호출되지 않으므로 pythonprepend는 아무런 영향을 미치지 않습니다. – repoman

관련 문제