[英]Boost.Python wrap raw pointer but expose methods
I have a class with methods that I get raw pointers to: 我有一个类,其中的方法可以获取原始的指针:
struct Foo {
int getSomething() const { .. }
void setSomethingElse(int ) { .. }
// .. lots more getters, setters, and other methods ..
};
Foo* p = make_something();
I had originally exposed this directly to python: 我最初将其直接暴露给python:
py::class_<Foo, Foo*, boost::noncopyable>("Foo", py::no_init)
.def("getSomething", &Foo::getSomething)
// ..
;
But the Foo
s I get come from an allocator that aggressively reuses memory, and my usage in python might hold onto these Foo*
s longer than they actually exist as valid objects in C++. 但是我得到的
Foo
来自积极地重用内存的分配器,而我在python中的使用可能会使这些Foo*
保持的时间比它们在C ++中实际存在的时间长。 So really I want to wrap them to save off some values, eg: 所以我真的想包装它们以节省一些值,例如:
struct FooWrapper {
Foo* p;
int val1;
FooWrapper(Foo* p) : p(p), val1(p->getVal1()) { }
operator Foo*() const { return p; }
int getVal1() const { return val1; }
};
FooWrapper fw(make_something());
But now in order to use the healthy number of functions of Foo
, I have to copy a whole bunch of stuff into FooWrapper
. 但是现在为了使用健康的
Foo
功能,我必须将一堆东西复制到FooWrapper
。 Or do I?? 还是我?? Is there a way to write and expose
FooWrapper
such that getVal1()
calls fw.getVal1()
but any other function calls fw.p->getSomethingElse()
in a way that I can avoid copying every other method on Foo
? 有没有一种方法可以编写和公开
FooWrapper
,使得getVal1()
调用fw.getVal1()
但其他函数调用fw.p->getSomethingElse()
可以避免在Foo
上复制其他所有方法? This is python after all, so I'm guessing there's something I can do with getattr
? 毕竟这是python,所以我猜我可以用
getattr
做些什么?
This was easier than I'd expected: 这比我预期的要容易:
struct FooWrapper
{
// as before
static py::object getattr(py::object self, std::string attr)
{
FooWrapper& fw = py::extract<FooWrapper&>(self);
return py::getattr(py::object{py::ptr(fw.p)}, attr.c_str());
}
};
With: 附:
py::class_<FooWrapper, boost::noncopyable>("Foo", py::no_init)
.def("getVal1", &FooWrapper::getVal1)
.def("getSomethingElse", &FooWrapper::getSomethingElse)
// ..
// and, finally, for everything else:
.def("__getattr__", &FooWrapper::getattr)
;
In python then: 然后在python中:
>>> f = get_foo() # this is really a FooWrapper
>>> f.getVal1
<bound method FooWrapper.getVal1 of <Test.FooWrapper object at 0x7faacd8d48e8>>
>>> f.getVal2
<bound method Foo.getVal2 of <Test.Foo object at 0x7faacd8d6210>>
>>> f.getVal3
AttributeError: 'Foo' object has no attribute 'getV3'
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.