[C++-sig] Problem: held type, std::auto_ptr, ReferenceErrors.
Prabhu Ramachandran
prabhu at aero.iitm.ernet.in
Wed Aug 20 05:23:10 CEST 2003
Hi,
I'm running into problems again. This time its related to pointers,
std::auto_ptr and possibly call policies. I'm using gcc (2.95.4).
The code is a little long winded since I'm experimenting with a couple
of problems in one shot.
// holder.hpp -----------------------------------------
#include <vector>
#include <iostream>
struct A {
virtual ~A() {}
virtual void f() = 0;
};
struct B: A{
void f() {std::cout << "B::f\n";}
};
struct HBase {
virtual ~HBase() {}
virtual std::size_t size() const = 0;
virtual A* get(const std::size_t n) = 0;
};
struct Holder : HBase {
Holder() {}
~Holder() {for (std::size_t i=0; i<arr.size(); ++i) delete arr[i];}
std::size_t size() const {return arr.size();}
void add(A* a) {arr.push_back(a);}
A* get(const std::size_t n) {return arr[n];}
private:
std::vector<A*> arr;
};
void func(A* a) {a->f();}
void f(HBase* h)
{
std::cout << h->size() << std::endl;
for (std::size_t i=0; i<h->size(); ++i)
h->get(i)->f();
}
--------------------------------------------------
I wrap this with Pyste using std::auto_ptr as the holder using a Pyste
file like so:
--------------------------------------------------
A = Class('A', 'holder.hpp')
B = Class('B', 'holder.hpp')
def held_type_func(name):
return 'std::auto_ptr< %s >'%name
holder(A, held_type_func)
holder(B, held_type_func)
HBase = Class('HBase', 'holder.hpp')
set_policy(HBase.get, return_value_policy(reference_existing_object))
Holder = Class('Holder', 'holder.hpp')
set_policy(Holder.get, return_value_policy(reference_existing_object))
add_wrapper = Wrapper('add_wrapper', """
void add_wrapper(Holder* c, std::auto_ptr< B> o)
{
c->add(o.get());
o.release();
}
""")
set_wrapper(Holder.add, add_wrapper)
module_code(''' implicitly_convertible<std::auto_ptr<B_Wrapper>, std::auto_ptr<B> > ();\n''')
func = Function('func', 'holder.hpp')
f = Function('f', 'holder.hpp')
--------------------------------------------------
I can attach the resulting cpp file if needed but using this Pyste
file I generate a holder.so module and test it like so:
--------------------------------------------------
from holder import *
b = B()
print "b.f():"
b.f()
print "func(b):"
func(b)
h = Holder()
h.add(b)
x = h.get(0)
print "x.f():"
x.f()
print "func(x):"
func(x)
print "f(h):"
f(h)
--------------------------------------------------
Problem 1:
^^^^^^^^^^
First spot of trouble is here:
b.f():
B::f
func(b):
B::f
x.f():
B::f
func(x):
Traceback (most recent call last):
File "test_holder.py", line 13, in ?
func(x)
Boost.Python.ArgumentError: Python argument types in
B.f(B)
did not match C++ signature:
f(Q227_GLOBAL_.N.holder.cppO3zZAb9B_Wrapper {lvalue})
f(1B {lvalue})
If I remove the HeldType and leave it as it is, everything works fine
upto the func(x) call that is. I also tried by specifying a
boost::shared_ptr<T> as the held type. I did not need to use the
add_wrapper in these two cases. That also seems to work just fine.
So this looks to be a bug similar to the one earlier where x.f() used
to fail when the held type was std::auto_ptr<T>. AFAIK, this does not
look to be a problem with Pyste.
Problem 2:
^^^^^^^^^^
The second problem is with the f(h) call. I get the following error
when I use either std::auto_ptr<T> or boost::shared_ptr<T> as the held
type or use no held type at all.
f(h):
1
Traceback (most recent call last):
File "test_holder.py", line 15, in ?
f(h)
ReferenceError: Attempt to return dangling pointer to object of type: 1A
I also tried to use a return_internal_reference<1>(); instead of the
return_value_policy(reference_existing_object)) and get the same
results. I also changed the HBase* argument to a Holder* argument
with the same results.
I'd appreciate very much if someone can tell me what I am doing wrong
here or if this is a bug.
Thanks!
prabhu
More information about the Cplusplus-sig
mailing list