2009/6/7 Taner Yildirim <ta...@seas.upenn.edu>

>  Dear Gustavo,
>
>
>
> Thanks for your detailed response. I hope pybindgen soon will have the full
> support for the stl-containers!
>
> I am looking forward to that particular version! Hopefully in the near
> future, I will learn more about pybindgen and maybe contribute something to
> the development of the project. It’s a great tool which has a much better
> and clean approach than swig and boos.python in my view!!!
>
>
>
> Back to my toy VecI example, unfortunately I am still having problem in
> getting the “add_function_as_contructor” work.
>
> Here is exactly what I am trying to do. In my earlier VecI class example, I
> had this function in tst1.h:
>
>
>
> void build_from_list( VecI &new_vec, std::vector<int> vi) {
>
> new_vec.clear(); new_vec=VecI(vi);}
>
>
>
> In c++ side, VecI is just a typedef for std::vector<int>. Hence this
> function works. For python side, pybindgen thinks that pybindgen container
> (i.e. std::Vector<int>) and my VecI class are two different things. Hence
> this function works as a bridge between them.
>
> Anyway, when I add this function as method with custom_name=FromList, I was
> able to build my vector from the python list:
>
>
>
> V=VecI()
>
> V=V.FromList(range(10))
>
>
>
> Now, I want to add this function as contructor rather than method so that I
> can simple say  myvector=VecI(range(10)), let say!
>
> In, pybindgen CppFunctionAsConstructor, it says that the first parameter
> should return “a pointer to the class” (not the class itself!).
>
> Hence, I changed my code like this:
>
>
>
> VecI  *from_list( std::vector<int> vi){
>
> VecI * p_new_vec=&vi;
>
> return p_new_vec;}
>
>
>
> Then, I add this to pybindgen as
>
>
>
>
> veci.add_function_as_constructor('from_list',ReturnValue.new('VecI*',caller_owns_return=True),
>
> [Parameter.new('std::vector<int>',' vec_int')])
>
>
>
> Of course, technically, everything seemed work! But the problem is that
> when I construct my vector, I am getting pointer and not the vector itself!
>
> What I mean is the following:
>
>
>
> V=VecI(range(10)) # works,  python does not complain it!
>
>
>
> But then V.size() returns a huge integer. I think V is now a pointer and
> not the vector.
>
> Probably the fix is very simple but I just do not see it! I tried to use &
> instead of **, *
>
> but then compiler complain that it can not convert int to  int*.
>
>
>
> Hope my problem is clear now.
>
Well, it is clear to me that you do not have deep knowledge of C/C++ memory
management, no offense intended :-)

Let's look at your code:

VecI  *from_list( std::vector<int> vi){

        VecI * p_new_vec=&vi;

        return p_new_vec;
}

The variable p_new_vec will be a pointer that points to the 'vi' variable.
'vi' is a parameter passed by value, which means it is an "automatic
variable".  When the function exits, 'vi' goes out of scope and is deleted.
However, you will have returned a pointer to what used to be a variable but
does not exist anymore; it points to garbage now.

The simplest solution is to copy the passed-in value, using a copy
constructor.  I would do a code like this insterad:

VecI  *from_list( std::vector<int> const &vi){

        VecI * p_new_vec= new std::vector<int> (vi);

        return p_new_vec;
}

This should work better.  Good luck.

-- 
Gustavo J. A. M. Carneiro
INESC Porto, Telecommunications and Multimedia Unit
"The universe is always one step beyond logic." -- Frank Herbert
_______________________________________________
Cplusplus-sig mailing list
Cplusplus-sig@python.org
http://mail.python.org/mailman/listinfo/cplusplus-sig

Reply via email to