我在Windows上使用Boost.Python 1.54和MSVC2010,並且存在一個指向第二個類中的一個類的指針,它。它似乎改變了數據類型。ArgumentError在Boost.Python類中存儲和檢索類中的指針:錯誤類型
這裏是我的課:
typedef unsigned int uint_t;
struct classA {
int intval;
unsigned int bitfield_member:1;
};
struct Collection {
classA * class_a_ptr;
};
這裏就是我揭露他們的蟒蛇(一些這個代碼最初是由PY ++自動生成的,但從那時起,我手工編輯它):
#include <boost/python.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/return_value_policy.hpp>
#include <boost/python/manage_new_object.hpp>
namespace bp = boost::python;
struct Collection_wrapper : Collection, bp::wrapper<Collection> {
Collection_wrapper(Collection const & arg)
: Collection(arg)
, bp::wrapper<Collection>(){
// copy constructor
}
Collection_wrapper()
: Collection()
, bp::wrapper<Collection>(){
// null constructor
}
static ::classA * get_class_a_ptr(Collection const & inst){
return inst.class_a_ptr;
}
static void set_class_a_ptr(Collection & inst, ::classA * new_value){
inst.class_a_ptr = new_value;
}
};
struct classA_wrapper : classA, bp::wrapper<classA> {
classA_wrapper(classA const & arg)
: classA(arg)
, bp::wrapper<classA>(){
// copy constructor
}
classA_wrapper()
: classA()
, bp::wrapper<classA>(){
// null constructor
}
::uint_t get_bitfield_member() const {
return bitfield_member;
}
void set_bitfield_member(::uint_t new_value){
bitfield_member = new_value;
}
};
BOOST_PYTHON_MODULE(render_lib_ext)
{
using namespace bp;
{ //::Collection
typedef bp::class_<Collection_wrapper> Collection_exposer_t;
Collection_exposer_t Collection_exposer = Collection_exposer_t("Collection");
bp::scope Collection_scope(Collection_exposer);
// original version, fails
Collection_exposer.add_property("class_a_ptr"
, bp::make_function((::classA * (*)(::Collection const &))(&Collection_wrapper::get_class_a_ptr), bp::return_internal_reference< >())
, bp::make_function((void (*)(::Collection &,::classA *))(&Collection_wrapper::set_class_a_ptr), bp::with_custodian_and_ward_postcall< 1, 2 >()));
}
{ //::classA
typedef bp::class_<classA_wrapper> classA_exposer_t;
classA_exposer_t classA_exposer = classA_exposer_t("classA");
bp::scope classA_scope(classA_exposer);
classA_exposer.def_readwrite("intval", &classA::intval);
classA_exposer.add_property("bitfield_member"
, (::uint_t (classA_wrapper::*)() const)(&classA_wrapper::get_bitfield_member)
, (void (classA_wrapper::*)(::uint_t))(&classA_wrapper::set_bitfield_member));
}
}
和這裏的蟒蛇測試行使它:
import unittest
import render_lib_ext as RL
class TestRenderLib(unittest.TestCase):
def test_globals(self):
coll=RL.Collection()
g = RL.classA()
g.intval=9801;
self.assertEqual(9801, g.intval)
coll.class_a_ptr = g # store pointer in collection
geg = coll.class_a_ptr # retrieve it
self.assertEqual(0, g.bitfield_member) # works
self.assertEqual(0, geg.bitfield_member) # fails with ArgumentError (type error)
self.assertEqual(9801, geg.intval) # fails! Is it not the same object?
它失敗,並在此錯誤第一個「失敗」行:
Traceback (most recent call last):
File "test2.py", line 18, in test_globals
self.assertEqual(0, geg.bitfield_member) # fails with ArgumentError (type error)
ArgumentError: Python argument types in
None.None(classA)
did not match C++ signature:
None(struct classA_wrapper {lvalue})
這對我來說似乎很奇怪,因爲classA_wrapper擴展了classA。我究竟做錯了什麼?有沒有不同的方式來做到這一點?我在python和C++方面非常有經驗,但這是我第一次進入Boost.Python。
謝謝!這看起來完全正確。在我的情況下,我有太多的實際成員來手動編輯所有Py ++生成的訪問器,所以相反,我讓'get_class_a_ptr'返回'classA_wrapper *'而不是'classA *',這似乎也行得通。 – GaryO