2012-12-03 33 views
1

我想一個C++轉換緩衝到一個python ::升壓::名單,我的C++類是:從C++緩衝區蟒蛇::升壓::名單

#include "boost/python/list.hpp" 

using namespace boost::python; 

class Buffer { 
public: 
    unsigned char* m_pBuff; 
    int m_iWidth; 
    int m_iHeight; 


    Buffer(cont 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::string 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; 
    } 
}; 

而蟒蛇升壓模塊定義爲:

using namespace boost::python; 

BOOST_PYTHON_MODULE(BufferMethods) 
{ 

    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) 
    ; 
} 

但是當我在Python運行模塊它返回此錯誤:

>>> from BufferMethods import * 
>>> Buff = Buffer(800, 600) 
>>> dataList = Buff.getList() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe0 in position 0: invalid continuation byte 
>>> 

我在做什麼錯?我正在使用Python 3.3。

+0

所以它是'boost :: python :: list',而不是'python :: boost :: list',不是嗎? –

回答

1

當您試圖將項追加到boost::python::list實例中時,附加項的python類型由作爲參數給出的C++對象的類型確定。由於您的data類型爲std::string,因此此附加操作正在嘗試創建Python字符串。猜測:我猜python字符串需要遵循一些佈局,並且由於您只是給它一些隨機數據,所以它不能將其解釋爲有效的字符串,這就是爲什麼你得到UnicodeDecodeError。我不知道究竟你打算用列表做什麼,和你想如何使您的緩衝區Python,但以下似乎工作(使用std::vector<char>作爲的data代替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) 
    ; 
} 

所以在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' 
+0

隨着你的建議,我得到這個錯誤:回溯(最近呼叫最後): 文件「」,第1行,在 TypeError:沒有to_python(by-value)轉換器找到C++類型:class std :: vector < char,class std :: allocator > – Marcus

+0

@Marcus你是怎麼得到這個錯誤的?你是否複製粘貼了我的代碼,還是將它與你的代碼合併?這聽起來像你忘了在'BOOST_PYTHON_MODULE(BufferMethods)' – enobayram

+0

中添加公開'std :: vector '的部分是的,你是對的! :D我沒有暴露std :: vector !謝謝!我想知道如果我可以使用這種方法來創建一個PhotoImage(tkinter)...來顯示圖像...也許使用PIL ... – Marcus

0

的問題是使用Python 2.7解決了......也許是錯誤的,因爲我使用的非官方構建python.boost從here引起的。

+0

我認爲這是因爲python2.x中的字符串處理和python3.x之間存在主要區別 – enobayram

+0

也許這就是爲什麼opencv沒有移植到python 3.x的原因 – Marcus

+0

也許...我不是python專家,我只是用它來編寫我的C++程序。但是我知道python2.x和python3.x之間存在顯着的非後向兼容性差異,所以原因可能是其他原因。最後,在兩者之間移植並不是微不足道的。 – enobayram