[Boost-users] [python] converting C++ object to PyObject

624 views
Skip to first unread message

Johan Råde

unread,
Jul 27, 2011, 5:06:16 AM7/27/11
to boost...@lists.boost.org
I have three C++ classes X, Y and Z that I have exported from C++ to
Python using python::class_.

Now I want to write a factory function like

PyObject* f(char c)
{
if(c == 'x')
return new X;
else if(c == 'y')
return new Y;
else if(c == 'z')
return new Z;
else
PyErr_SetString(PyExc_ValueError, "Bad function argument");
}

and export that function to Python.

What is missing here is code that converts X*, Y* and Z* to PyObject*.
How do I write that?

Thank you,
Johan

_______________________________________________
Boost-users mailing list
Boost...@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users

Johan Råde

unread,
Jul 29, 2011, 7:29:07 AM7/29/11
to boost...@lists.boost.org
On 2011-07-27 11:06, Johan Råde wrote:

> What is missing here is code that converts X*, Y* and Z* to PyObject*.
> How do I write that?

I figured out the answer:

boost::python::api::object(...).ptr()

It is not easy to find these things in boost.python documentation.

--Johan

Johan Råde

unread,
Jul 29, 2011, 8:48:32 AM7/29/11
to boost...@lists.boost.org
On 2011-07-29 13:29, Johan Råde wrote:
> On 2011-07-27 11:06, Johan Råde wrote:
>
>> What is missing here is code that converts X*, Y* and Z* to PyObject*.
>> How do I write that?
>
> I figured out the answer:
>
> boost::python::api::object(...).ptr()

No, that did not work.

When I run the following code

C++:

#include<boost/noncopyable.hpp>
#include<boost/python.hpp>

using boost::noncopyable;
using namespace boost::python;

class X : noncopyable {};

PyObject* f()
{
return api::object(new X).ptr();
}

BOOST_PYTHON_MODULE(Foo)
{
class_<X, noncopyable>("X");
def("f", &f);
}

Python:

import Foo
Foo.f()


then an exception, with the following error string, is thrown from the
api::object constructor:

TypeError: No to_python (by-value) converter found for C++ type:
class X

Am I using api::object incorrectly, or should I not use api::object at
all but do something completely different?

Ravi

unread,
Aug 8, 2011, 12:21:12 AM8/8/11
to boost...@lists.boost.org
On Friday, July 29, 2011 05:48:32 AM Johan Råde wrote:
> When I run the following code
>
> C++:
>
> #include<boost/noncopyable.hpp>
> #include<boost/python.hpp>
>
> using boost::noncopyable;
> using namespace boost::python;
>
> class X : noncopyable {};
>
> PyObject* f()
> {
> return api::object(new X).ptr();
> }
>
> BOOST_PYTHON_MODULE(Foo)
> {
> class_<X, noncopyable>("X");
> def("f", &f);
> }
>
> Python:
>
> import Foo
> Foo.f()
>
>
> then an exception, with the following error string, is thrown from the
> api::object constructor:
>
> TypeError: No to_python (by-value) converter found for C++ type:
> class X
>
> Am I using api::object incorrectly, or should I not use api::object at
> all but do something completely different?

As far as I can tell, the above should work. Could you please file a ticket on
trac?

Ravi

Johan Råde

unread,
Dec 3, 2011, 7:13:51 AM12/3/11
to boost...@lists.boost.org
On 8/8/2011 6:21 AM, Ravi wrote:
> On Friday, July 29, 2011 05:48:32 AM Johan Råde wrote:
...

>> Am I using api::object incorrectly, or should I not use api::object at
>> all but do something completely different?
>
> As far as I can tell, the above should work. Could you please file a ticket on
> trac?
>
> Ravi

Now I have finally done that:
https://svn.boost.org/trac/boost/ticket/6203

--Johan

Johan Råde

unread,
Dec 4, 2011, 4:11:43 AM12/4/11
to boost...@lists.boost.org
On 12/3/2011 1:13 PM, Johan Råde wrote:
> On 8/8/2011 6:21 AM, Ravi wrote:
>> On Friday, July 29, 2011 05:48:32 AM Johan Råde wrote:
> ...
>>> Am I using api::object incorrectly, or should I not use api::object at
>>> all but do something completely different?
>>
>> As far as I can tell, the above should work. Could you please file a
>> ticket on
>> trac?
>>
>> Ravi
>
> Now I have finally done that:
> https://svn.boost.org/trac/boost/ticket/6203
>
> --Johan

It turned out not to be a bug.
The python::object constructor does not take a raw pointer, you must
give it a shared pointer. See https://svn.boost.org/trac/boost/ticket/6203

Uthpal Urubail

unread,
Dec 5, 2011, 7:20:59 AM12/5/11
to boost...@lists.boost.org
All,
I noticed the below crashes[run time error because of space in string]
Is there a possibility to handle this situation? [without explicitly
calling split]

string s = " 12252001";
int offsets[] = {5,2,4};
offset_separator f(offsets, offsets+3);
tokenizer<offset_separator> tok(s,f);
for(tokenizer<offset_separator>::iterator beg=tok.begin();
beg!=tok.end();++beg)
int val = boost::lexical_cast<int>( *beg);

Thanks
UJ

Igor R

unread,
Dec 5, 2011, 7:49:56 AM12/5/11
to boost...@lists.boost.org
> I noticed the below crashes[run time error because of space in string]
> Is there a possibility to handle this situation? [without explicitly
> calling split]
>
>   string s = "   12252001";
>   int offsets[] = {5,2,4};
>   offset_separator f(offsets, offsets+3);
>   tokenizer<offset_separator> tok(s,f);
>   for(tokenizer<offset_separator>::iterator beg=tok.begin();
> beg!=tok.end();++beg)
>           int val = boost::lexical_cast<int>( *beg);


You should explicitly trim every token (use boost/algorithm/string/trim.hpp).
Alternatively, you could use more flexible facility, like Spirit.

Reply all
Reply to author
Forward
0 new messages