[C++-sig] Conversion problem
Hello,
I wonder if someone could help me with a tricky conversion between c++
and python types (well, tricky for me!)
I have a c++ library that I would like to use in python via Boost::Python
One function fills a c++ unsigned char* buffer. It has two overloads:
unsigned char * getPixels(int deviceID);
bool getPixels(int id, unsigned char * pixels);
How would I go about getting that data into a python object, a string in
particular? I seem to face several problems:
/
1) unsigned char* does not have a to_python converter to Py_String.
I tried this:
struct uchar_ptr_to_str
{
static PyObject* convert(unsigned char* p)
{
return incref( str(p).ptr());
}
static PyTypeObject const *get_pytype () {return &PyString_Type; }
};
struct uchar_to_str
{
static PyObject* convert(unsigned char& p)
{
return incref( str(p).ptr());
}
static PyTypeObject const *get_pytype () {return &PyString_Type; }
};
BOOST_PYTHON_MODULE(pyVideoInput)
{
to_python_converter< unsigned char*, uchar_ptr_to_str, true >();
to_python_converter< unsigned char, uchar_to_str, true >();
class_("videoInput")
.def("getPixels", &videoInput::getPixels,
return_value_policy())
;
}
/
2) How do I allocate memory in a python string and then pass the pointer
through boost python, to be filled by the c++ function?
In c++, the library would be used like this:
videoInput vi;
unsigned char * buffer = new unsigned char[size];
vi.getPixels(device, buffer);
The buffer could be pretty big so I want to pass by pointer, not by value
The alternative would be to use the overload which returns the pointer,
but I can't get that to compile with bjam. I get the dreaded:
make_instance.hpp(24) : error C2027:
use of undefined type 'boost::STATIC_ASSERTION_FAILURE
when I try to return a pointer...
Thanks for any help freeing me from my confusion!
Regards
Si
___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] Returning a simple char *
Sending
again, as my original reply apparently got lost, sorry if it didn't.
IMO, the easiest route would be to wrap the member functions :
namespace {
std::string video_getDeviceName_wrapped(int deviceID)
{
char* name = videoInput::getDeviceName(devideID);
std::string result(name);
// free 'name' memory if needed
return result;
}
}
and then ::
using namespace boost::python;
BOOST_PYTHON_MODULE(pyVideoInput)
{
class_("videoInput")
.def("getDeviceName", &video_getDeviceName_wrapped)
.staticmethod("getDeviceName")
;
}
and you should be done.
___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] Conversion problem
On Wed, Jan 13, 2010 at 11:00 AM, Simon Pickles
wrote:
> Hello,
>
> I wonder if someone could help me with a tricky conversion between c++ and
> python types (well, tricky for me!)
>
> I have a c++ library that I would like to use in python via Boost::Python
>
> One function fills a c++ unsigned char* buffer. It has two overloads:
>
> unsigned char * getPixels(int deviceID);
> bool getPixels(int id, unsigned char * pixels);
>
In both cases the easiest solution would be create small wrappers
around the functions:
std::string getPixels(int i ){ ... }
and expose it.
Another solution would be to use ctypes module to call those functions.
In both cases Py++ can help you:
http://language-binding.net/pyplusplus/documentation/functions/transformation/transformation.html
--
Roman Yakovenko
C++ Python language binding
http://www.language-binding.net/
___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] Conversion problem
Simon,
it seems that I wrapped the same videoinput library you're using.
I wrapped the getPixels the following way : python script is responsible
of the memory allocation for pixels buffer (in a correctly sized string).
The getPixels function is wrapped as follows :
namespace {
bool videoInput_getPixels(videoInput& input, int device_id,
python::object memory_buffer)
{
PyObject* pyObject = memory_buffer.ptr();
if (PyString_CheckExact(pyObject))
{
Py_ssize_t string_size = PyString_Size(pyObject);
if (string_size >= Py_ssize_t(input.getWidth(device_id)) *
Py_ssize_t(input.getHeight(device_id)) * Py_ssize_t(3))
{
unsigned char* pixels = reinterpret_castchar*>(PyString_AsString(pyObject));
return input.getPixels(device_id, pixels, false, false);
}
}
return false;
}
};
python::class_ klass("VideoInput");
klass.def("getPixels", videoInput_getPixels);
This certainly lacks some error checking for the actual 'memory_buffer'
parameter type, but can give you a clue.
HTH,
Nicolas
___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig
[C++-sig] Simple , , I think .. type conversion question C++ -> python
OK. Here's what I've been stuck with all today .. I have a 3rd party C++
program function which returns a boost::variant (and its inverse)
my_variant my_variant_of_string(const std::string& str)
This one takes a string & returns a variant, and am trying to wrap this
in python, so that there I can have
>>> my_variant_of_string('hello')
'hello'
>>> my_variant_of_string('1.2')
1.2
>>> my_variant_of_string('10')
10
Simple, eh? .. The reduced code below compiles, creating the python
function correctly, but I have not successfully defined
to_python_value/to_python_converter statement(s), so the python
predictably fails with a ".. no to_python .. converter for ..
boost::variant .." when run.
I can find lots of helpful references to such converters of classes (eg
http://misspent.wordpress.com/2009/09/27/how-to-write-boost-python-converters/),
but cannot see how I should use the to_python_value functionality to
express the "convert the output of this function to a string, int or
double as appropriate".
Thanks
Tim "novice, but learning" Couper
-- my_variant.cpp --
#include
typedef boost::variant my_variant;
template
bool from_string(T& t,const std::string& s, std::ios_base&
(*f)(std::ios_base&))
{
std::istringstream iss(s);
return !(iss >> f >> t).fail();
}
namespace var {
my_variant my_variant_of_string(const std::string& str)
// return a float, int or string depending on input parameter
content
{
my_variant param;
double dval; int ival;
if (str.find(".") != std::string::npos) {
if (from_string(dval,str,std::dec)) {
param = dval;
}
}
else if (from_string(ival,str,std::dec) ) {
param = ival;
}
else {
param= str;
}
return param;
}
}// var
#include
#include
BOOST_PYTHON_MODULE(var)
{
using namespace boost::python;
def("my_variant_of_string", &var::my_variant_of_string);
}
___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] Simple , , I think .. type conversion question C++ -> python
Tim Couper wrote:
OK. Here's what I've been stuck with all today .. I have a 3rd party C++
program function which returns a boost::variant (and its inverse)
my_variant my_variant_of_string(const std::string& str)
This one takes a string & returns a variant, and am trying to wrap this
in python, so that there I can have
>>> my_variant_of_string('hello')
'hello'
>>> my_variant_of_string('1.2')
1.2
>>> my_variant_of_string('10')
10
Simple, eh? ...
How about something like (not tested):
using boost::python::object;
typedef variant<...> variant_t;
variant_t makes_variant_from(string s); // defined elsewhere
//
// visitor for converting contents of visitor to object
//
struct vc : boost::static_visitor
{
template
object operator()(const T& v) const
{
return v;
}
};
bp::object
thunk(string s)
{
variant_t v = makes_variant_from(s);
return boost::apply_visitor(vc(), v);
}
BOOST_PYTHON_MODULE(mod)
{
def("f", &thunk);
}
You could probably use this to just register a converter from variant to
vanilla boost::python::object as well, if this is more convenient...
-t
___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] Simple , , I think .. type conversion question C++ -> python
Troy
Thanks .. your hints are most helpful .. I'll be back :-)
Tim
On 13/01/2010 19:10, troy d. straszheim wrote:
Tim Couper wrote:
OK. Here's what I've been stuck with all today .. I have a 3rd party
C++ program function which returns a boost::variant (and its inverse)
my_variant my_variant_of_string(const std::string& str)
This one takes a string & returns a variant, and am trying to wrap
this in python, so that there I can have
>>> my_variant_of_string('hello')
'hello'
>>> my_variant_of_string('1.2')
1.2
>>> my_variant_of_string('10')
10
Simple, eh? ...
How about something like (not tested):
using boost::python::object;
typedef variant<...> variant_t;
variant_t makes_variant_from(string s); // defined elsewhere
//
// visitor for converting contents of visitor to object
//
struct vc : boost::static_visitor
{
template
object operator()(const T& v) const
{
return v;
}
};
bp::object
thunk(string s)
{
variant_t v = makes_variant_from(s);
return boost::apply_visitor(vc(), v);
}
BOOST_PYTHON_MODULE(mod)
{
def("f", &thunk);
}
You could probably use this to just register a converter from variant
to vanilla boost::python::object as well, if this is more convenient...
-t
___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig
No virus found in this incoming message.
Checked by AVG - www.avg.com
Version: 9.0.725 / Virus Database: 270.14.138/2618 - Release Date: 01/13/10
07:35:00
___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] [boost.python] How can I wrap operator==?
On Mittwoch 13 Januar 2010, Roman Yakovenko wrote:
> On Wed, Jan 13, 2010 at 8:57 AM, blp330 wrote:
> > class Document
> > {
> > public:
> >
> >
> > bool operator==(const Document& other) const
> > {
> > return Compare(other);
> > }
> [...]
> If I understand you right, you need:
>
> 1. define new global function, which takes Document& as the first argument
>
> bool Document_EqualWrap( const Document& x, const Document& y ){...}
Not necessary AFAIK, a member function should work, too.
(i.e. directly exposing &Document::operator==)
> 2. Expose it:
>
> ...
> .def( "__eq__", &Document_EqualWrap )
>
> Is not the working code, but it should give you a direction.
Yes, I think that's what he was missing.
--
Ciao, / /.o.
/--/ ..o
/ / ANS ooo
signature.asc
Description: This is a digitally signed message part.
___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig
[C++-sig] A nice Boost.Python and Py++ usage example
http://frontiersin.org/psychology/psychology/paper/10.3389/neuro.11/011.2009/html/ The articles talks about some science fiction ( for me:-) ), but also has few paragraphs related to Boost.Python and Py++. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ ___ Cplusplus-sig mailing list [email protected] http://mail.python.org/mailman/listinfo/cplusplus-sig
[C++-sig] Boost and wxWidgets
Hi.
I am testing the following source code:
Canvas.h
#ifndef _CANVAS_H_
#define _CANVAS_H_
#include
#include "wx/wx.h"
class CanvasFrame
{
protected:
wxFrame* _frame;
public:
CanvasFrame(const std::string& pTitle);
~CanvasFrame(void);
void Plot(void);
};
#endif /* _CANVAS_H_ */
--
Canvas.cpp
--
#include
#include "canvas.h"
CanvasFrame::CanvasFrame(const std::string& pTitle)
{
_frame = new wxFrame(NULL, wxID_ANY,
wxString::FromAscii(pTitle.c_str()));
}
CanvasFrame::~CanvasFrame(void)
{
if(_frame) {
delete _frame;
}
}
void CanvasFrame::Plot(void)
{
}
---
wrapper.cpp
---
#include
#include "canvas.h"
using namespace boost::python;
BOOST_PYTHON_MODULE(canvas)
{
class_("CanvasFrame", init())
.def("Plot", &CanvasFrame::Plot)
;
}
And to generate the module "canvas.so" I execute:
g++ -shared -g -I. -I/usr/include/python2.6 -lpython2.6 canvas.cpp
wrapper.cpp /usr/lib64/libboost_python.so -fPIC `wx-config --cxxflags`
`wx-config --libs` -o canvas.so
"canvas.so" is generated without any problems but when I execute in the
python console the next code:
>>> import canvas
>>> a = canvas.CanvasFrame('My Plot Window')
I have the next errors:
(process:3521): GLib-GObject-CRITICAL **: gtype.c:2458: initialization
assertion failed, use IA__g_type_init() prior to this function
(process:3521): GLib-CRITICAL **: g_once_init_leave: assertion
`initialization_value != 0' failed
(process:3521): Gdk-CRITICAL **: gdk_cursor_new_for_display: assertion
`GDK_IS_DISPLAY (display)' failed
(process:3521): GLib-GObject-CRITICAL **: gtype.c:2458: initialization
assertion failed, use IA__g_type_init() prior to this function
And more, and more, and more. I have watched the examples of
http://wiki.python.org/moin/boost.python/ExportingClasses
but I have not seen any problem. They can help me? Thanks!
P.D. Sorry for my english!
___
Cplusplus-sig mailing list
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig
