When you're trying to append items into a boost::python::list
instance, the python type of the appended item is determined from the type of the C++ object given as the argument. Since your data
is of type std::string
, this append operation is attempting to create a Python string. Speculation: I guess python strings need to adhere to some layout, and since you're simply feeding it some random data, it fails to interpret it as a valid string, that's why you get a UnicodeDecodeError. I don't know what exactly you intend to do with the list, and how you would like to expose your buffer to Python, but the following seems to work (using a std::vector<char>
as the type of data
instead of std::string
):
#include <boost/python.hpp>
#include <boost/python/list.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
#include <vector>
using namespace boost::python;
class Buffer {
public:
unsigned char* m_pBuff;
int m_iWidth;
int m_iHeight;
Buffer( const int p_iWidth, const int p_iHeight ) {
m_pBuff = new unsigned char[p_iWidth * p_iHeight];
m_iWidth = p_iWidth;
m_iHeight = p_iHeight;
}
~Buffer() { delete[] m_pBuff; }
/* Class Functions */
list getList ( void ) {
list l;
l.append(m_iWidth);
l.append(m_iHeight);
std::vector<char> data(m_iWidth*m_iHeight);
unsigned char* pBuff = m_pBuff;
for ( int i = 0; i < m_iWidth * m_iHeight; ++i, ++pBuff ) {
data[i] = (char) *pBuff;
}
l.append(data);
return l;
}
};
BOOST_PYTHON_MODULE(BufferMethods)
{
class_<std::vector<char> >("CharVec")
.def(vector_indexing_suite<std::vector<char> >());
class_<Buffer>("Buffer", init<const int, const int>())
.add_property("width", &Buffer::m_iWidth)
.add_property("height", &Buffer::m_iHeight)
/* Other functions */
.def("getList", &Buffer::getList)
;
}
So in python (3.2):
In [1]: from BufferMethods import *
In [2]: Buff = Buffer(800,600)
In [3]: dataList = Buff.getList()
In [4]: dataList[2]
Out[4]: <BufferMethods.CharVec at 0x18172d0>
In [5]: dataList[2][2]
Out[5]: '\x00'