Opened 20 years ago
Closed 16 years ago
#138 closed Support Requests (Fixed)
problem with overridable virtual functions in Boost.Python
Reported by: | nobody | Owned by: | david_abrahams |
---|---|---|---|
Milestone: | Component: | python USE GITHUB | |
Version: | None | Severity: | |
Keywords: | Cc: |
Description
I'm having problems overriding functions in Python with Boost. The examples provided on the website seem to work. However, all the examples I have managed to find have involved callback classes with virtual function overrides having zero arguments. I am trying to override functions with multiple arguments with no success. I get consistent errors when trying to manipulate multi-argument virtual functions polymorphically from a C++ extension. Im currently using Visual Studio .Net and Python 2.2.2. The following code demostrates the problem: ------------------Begin Code --------------------------- C++ code: #include <iostream> #include <string> class Entity { public: Entity() {Class = "Entity"; } Entity(const Entity& e) { this->Class = e.Class; } std::string virtual GetClass(std::string PreFix) { return Class + PreFix; } public: std::string Class; }; class SimpleEntity : public Entity { public: SimpleEntity() { this->Class = "SimpleEntity"; } SimpleEntity(const SimpleEntity& se) { this- >Class = se.Class; } std::string virtual GetClass(std::string PreFix) { return Class + PreFix; } }; #include <boost/python/module.hpp> #include <boost/python/def.hpp> #include <boost/python/args.hpp> #include <boost/python/class.hpp> #include <boost/python/overloads.hpp> #include <boost/python/call_method.hpp> using namespace boost::python; std::string Test(Entity* e, std::string PreFix) { return e->GetClass(PreFix); } class EntityWrap : public Entity { public: EntityWrap(PyObject* self_) : self(self_) {} EntityWrap(PyObject* self_, const Entity& e) : self(self_), Entity(e) {} std::string GetClass(std::string PreFix) { return call_method<std::string>(self, "GetClass", PreFix); } std::string default_GetClass( Entity& e, std::string PreFix) { return e.Entity::GetClass(PreFix); } private: PyObject* self; }; class SimpleEntityWrap : public SimpleEntity { public: SimpleEntityWrap(PyObject* self_) : self(self_) {} SimpleEntityWrap(PyObject* self_, const SimpleEntity& se) : self(self_), SimpleEntity(se) {} std::string GetClass(std::string PreFix) { return call_method<std::string>(self, "GetClass", PreFix); } std::string default_GetClass( SimpleEntity& se, std::string PreFix) { return se.SimpleEntity::GetClass (PreFix); } private: PyObject* self; }; BOOST_PYTHON_MODULE(hello) { class_<Entity, EntityWrap>("Entity") .def(init<const Entity&>()) .def("GetClass", &EntityWrap::default_GetClass) .def_readwrite("Class", &Entity::Class); ; class_<SimpleEntity, SimpleEntityWrap, bases<Entity> >("SimpleEntity") .def(init<const SimpleEntity&>()) .def("GetClass", &SimpleEntityWrap::default_GetClass) ; def("Test", Test); } Python Code: Python 2.2.2 (#37, Oct 14 2002, 17:02:34) [MSC 32 bit (Intel)] on win32 Type "copyright", "credits" or "license" for more information. IDLE 0.8 -- press F1 for help >>> from hello import * >>> class DerivedEntity(SimpleEntity): def __init__(self): SimpleEntity.Class = "DerivedEntity" def GetClass(self,x): return self.Class + x >>> e = Entity() >>> Test(e, " a test") Traceback (most recent call last): File "<pyshell#4>", line 1, in ? Test(e, " a test") TypeError: bad argument type for built-in operation >>> s = SimpleEntity() >>> Test(s, " a test") Traceback (most recent call last): File "<pyshell#6>", line 1, in ? Test(s, " a test") TypeError: bad argument type for built-in operation >>> d = DerivedEntity() >>> Test(d, " a test") Traceback (most recent call last): File "<pyshell#8>", line 1, in ? Test(d, " a test") TypeError: bad argument type for built-in operation >>> e.Class 'Entity' >>> e.GetClass(" a test") Traceback (most recent call last): File "<pyshell#10>", line 1, in ? e.GetClass(" a test") TypeError: bad argument type for built-in operation >>> s.Class 'DerivedEntity' >>> s.GetClass("a test") Traceback (most recent call last): File "<pyshell#12>", line 1, in ? s.GetClass("a test") TypeError: bad argument type for built-in operation >>> d.Class 'DerivedEntity' >>> d.GetClass(" a test") 'DerivedEntity a test' >>> ------------------End Code --------------------------- Am I missing something? Any help would be appreciated. Thanks, Vince
Change History (4)
comment:2 by , 20 years ago
Logged In: NO Thanks for the fix Joel, everything works as expected now. I really appreciate your prompt response. One last thing, I am assuming that this solution is only applicable to the version of boost currently in cvs? When I tried the same fix with version 1.29 it generates a compile error. Much Thanks, Vince The above mentioned error in case you weren't aware. C:\Documents and Settings\thomasinov\Desktop\boost_1_29_0 \boost\python\detail\de f_helper.hpp(131) : error C2440: 'return' : cannot convert from 'std::basic_stri ng<_Elem,_Traits,_Ax> ' to 'const char *' with [ _Elem=char, _Traits=std::char_traits<char>, _Ax=std::allocator<char> ] There is no context in which this conversion is possible C:\Documents and Settings\thomasinov\Desktop\boost_1_29_0\boost\python\d etail\def_helper.hpp(130) : while compiling class-template member function 'cons t char *boost::python::detail::def_helper<T1,T2,T3>::doc(void) const' with [ T1=std::basic_string<char,std::char_traits<char>,std::allocator<c har >> (__thiscall EntityWrap::* )(std::string), T2=boost::python::detail::not_specified, T3=boost::python::detail::not_specified ] C:\Documents and Settings\thomasinov\Desktop\boost_1_29_0\boost\python\c lass.hpp(362) : see reference to class template instantiation 'boost::python::de tail::def_helper<T1,T2,T3>' being compiled with [ T1=std::basic_string<char,std::char_traits<char>,std::allocator<c har >> (__thiscall EntityWrap::* )(std::string), T2=boost::python::detail::not_specified, T3=boost::python::detail::not_specified ] C:\Documents and Settings\thomasinov\Desktop\boost_1_29_0\boost\python\c lass.hpp(227) : see reference to function template instantiation 'void boost::py thon::class_<T,X1,X2,X3>::dispatch_def(const void *,const char *,std::basic_stri ng<_Elem,_Traits,_Ax> ,std::basic_string<_Elem,_Traits,_Ax> & )' being compiled with [ T=Entity, X1=EntityWrap, X2=boost::python::detail::not_specified, X3=boost::python::detail::not_specified, _Elem=char, _Traits=std::char_traits<char>, _Ax=std::allocator<char> ] hello.cpp(141) : see reference to function template instantiation 'boost ::python::class_<T,X1,X2,X3>::self &boost::python::class_<T,X1,X2,X3>::def(const char *,std::basic_string<_Elem,_Traits,_Ax> ,std::basic_string<_Elem, _Traits,_A x> & )' being compiled with [ T=Entity, X1=EntityWrap, X2=boost::python::detail::not_specified, X3=boost::python::detail::not_specified, _Elem=char, _Traits=std::char_traits<char>, _Ax=std::allocator<char> ]
comment:3 by , 20 years ago
Logged In: YES user_id=237817 Hi Vince, Yes, the solution requires the latest CVS code which is almost Boost 1.30.0 in just a few more days. Pardon me for not mentioning that. However, there is actually a 1.29.0 solution. See http://article.gmane.org/gmane.comp.python.c++/1861 for details. Cheers, -- Joel de Guzman joel at boost-consulting.com http://www.boost-consulting.com http://spirit.sf.net
comment:4 by , 16 years ago
Status: | assigned → closed |
---|
Note:
See TracTickets
for help on using tickets.