다음은 내가 원하는 것으로 생각하는 작은 예제입니다. 전체 프로시 저는 Boost.Python이 파이썬에서 특정 유형의 인스턴스를 생성 할 때 실제로 다른 클래스를 사용하도록 알려주는 "holder"클래스를 사용하고 파이썬 객체를 사용자 정의의 모든 생성자에 대한 첫 번째 인수로 전달해야합니다 래퍼 클래스.
http://www.boost.org/doc/libs/1_48_0/libs/python/doc/v2/class.html
(특히 "HeldType 의미"설명을 참조하십시오) : 당신은 여기에 더 많은 정보를 찾을 수 있습니다.
#include "boost/python.hpp"
namespace bp = boost::python;
class Base {
public:
virtual double go(int x) const = 0;
virtual ~Base() {}
};
class PyBase : public Base {
public:
explicit PyBase(PyObject* self) : _self(self) {
Py_INCREF(_self); // THIS LEAKS MEMORY IF THERE'S NO DECREF!
}
virtual double go(int x) const {
return bp::call_method<double>(_self, "go", x);
}
private:
PyObject * _self;
};
BOOST_PYTHON_MODULE(example) {
bp::class_<Base,PyBase,boost::noncopyable>(
"Base",
bp::init<>() // the PyObject* arg is implicit
)
.def("go", &PyBase::go)
;
}
그러나 몇 가지주의 사항이있다 :
당신이 Base
에서 상속 파이썬에서 go
를 구현하지 않는 경우, 당신은 무한 재귀에 대한 인정 파이썬 예외 메시지가 나타납니다. 또한 가상 함수를 C++로 다시 변환하는 방법을 잘 모르겠다. 기본 구현이 있다면 (아마도 비슷한 것을하는 bp::wrapper
코드를 보면 알 수있다). 당신이 참조 또는 포인터에 의한 C++ 함수에서 Base
개체를 반환하는 경우
, 당신은 당신이 실제로 반환로 시작하는 PyBase 객체이었다 인스턴스 않는 한 PyBase
개체를 포함하는 파이썬의 객체가되지 않습니다 (즉 의미가 있습니다 물론 그것에 대해 생각한다면). 당신이 값으로 돌아가려면
, 당신은 당신이 bp::class_
통화에서 boost::noncopyable
템플릿 인수를 제거하기 전에 첫 번째 인수로 PyObject*
소요 복사 생성자를 추가해야합니다.
생성자의 문은 "your code"가이 객체에 대한 추가 참조를 취한다는 것을 파이썬에게 알려줍니다. 그러나 해당하는 Py_DECREF
을 추가하는 방법이 분명하지 않습니다. 가지고있는 모든 항목이 인 경우 Base*
인 경우 나중에 PyObject*
을 가져올 수 없습니다.
위의 한 가지 문제는 컨테이너가 bp::handle<>
또는 bp::object
이고 컨테이너에 넣기 위해 self
의 컨테이너 중 하나를 구성하는 것입니다. 그러나이 경우 정적 소멸자 시간에 파이썬 소멸자가 호출되면 세그먼트 화 오류가 발생하므로 프로그램이 종료되기 전에 해당 컨테이너가 비어 있는지 확인해야합니다.
컨테이너에서 개체를 배치? – Dani
그것을 무시하는 C++ 생성자가 파이썬에 의해 호출되었습니다. –
나는 내가 말한 것이 애매하다는 것을 깨달았다. 내가 말하는 컨테이너에는 객체 자체가 아니라 참조 만 들어 있습니다. 사실 포인터의 std :: map입니다. –