Wrapping Just an Abstract Base
I'm having a mental breakdown on this one. I have a factory returning a pointer to an abstract base class that I've wrapped. However, I can't logically wrap the actual derived class because it's generated in a plugin. So, when I go to make a call on one of the abstract functions it fails with an AttributeError exception. Is there anyway to handle this in a clean manner that keeps the API near the C++ API? I've played around with writing wrapper functions (taking the base class pointer) that are defined on the class using the same name as the virtual function. Sadly, from my mailing list searches on this subject it seems this is a bad idea and can possibly lead to lookup loops? It does seem to run properly, though. Would love some feedback or a kick in the head if I'm missing something in the docs and sites. Thanks. --temas
Thomas Muldowney <temas@box5.net> writes:
I'm having a mental breakdown on this one. I have a factory returning a pointer to an abstract base class that I've wrapped.
Abstract* factory();
However, I can't logically wrap the actual derived class because it's generated in a plugin.
What do you mean by "plugin"? Some other extension module?
So, when I go to make a call on one of the abstract functions it "pure virtual"-------------------^^^^^^^^? fails with an AttributeError exception. Is there anyway to handle this in a clean manner that keeps the API near the C++ API?
class_<Abstract, non_copyable>("Abstract", no_init) .def("pure_virtual_function1", &Abstract::pure_virtual_function1) .def("pure_virtual_function2", &Abstract::pure_virtual_function2) ... ; ??
I've played around with writing wrapper functions (taking the base class pointer) that are defined on the class using the same name as the virtual function. Sadly, from my mailing list searches on this subject it seems this is a bad idea and can possibly lead to lookup loops?
Please post some code which illustrates what you're doing. I'm sure it's unneccessary, but I can't quite understand it either.
It does seem to run properly, though. Would love some feedback or a kick in the head if I'm missing something in the docs and sites.
Sorry, remote cranial kicks cost extra. -- Dave Abrahams Boost Consulting www.boost-consulting.com
*sigh* no more 2am emails. Here's some code that is similar: #include <iostream> #include <boost/python.hpp> using namespace boost::python; class Base { public: virtual void foo() = 0; }; class Base_Wrap : public Base { public: void foo() { std::cout << "Base_Wrap foo()" << std::endl; } }; class Deriv : public Base { public: void foo() { std::cout << "Deriv foo()" << std::endl; } }; Base* createBase() { Base* b = new Deriv; return b; } BOOST_PYTHON_MODULE(testA) { class_<Base, Base_Wrap, boost::noncopyable>("Base", no_init); def("createBase", createBase, return_value_policy<manage_new_object>()); } It seemed implied to me by the docs and some other emails that foo should not be defined in Base. I had done that in the past, but changed on this refactoring of the code. Although not demonstrated in this code, when I say plugin I mean a dynamic library/shared object that is loaded using dynlib. It actually provides the implementation of the factory. --temas On Sat, 2003-07-26 at 06:29, David Abrahams wrote:
Thomas Muldowney <temas@box5.net> writes:
I'm having a mental breakdown on this one. I have a factory returning a pointer to an abstract base class that I've wrapped.
Abstract* factory();
However, I can't logically wrap the actual derived class because it's generated in a plugin.
What do you mean by "plugin"? Some other extension module?
So, when I go to make a call on one of the abstract functions it "pure virtual"-------------------^^^^^^^^? fails with an AttributeError exception. Is there anyway to handle this in a clean manner that keeps the API near the C++ API?
class_<Abstract, non_copyable>("Abstract", no_init) .def("pure_virtual_function1", &Abstract::pure_virtual_function1) .def("pure_virtual_function2", &Abstract::pure_virtual_function2) ... ;
??
I've played around with writing wrapper functions (taking the base class pointer) that are defined on the class using the same name as the virtual function. Sadly, from my mailing list searches on this subject it seems this is a bad idea and can possibly lead to lookup loops?
Please post some code which illustrates what you're doing. I'm sure it's unneccessary, but I can't quite understand it either.
It does seem to run properly, though. Would love some feedback or a kick in the head if I'm missing something in the docs and sites.
Sorry, remote cranial kicks cost extra.
Thomas Muldowney <temas@box5.net> writes:
*sigh* no more 2am emails.
Here's some code that is similar:
#include <iostream> #include <boost/python.hpp>
using namespace boost::python;
class Base { public: virtual void foo() = 0; };
class Base_Wrap : public Base { public: void foo() { std::cout << "Base_Wrap foo()" << std::endl; } };
class Deriv : public Base { public: void foo() { std::cout << "Deriv foo()" << std::endl; } };
Base* createBase() { Base* b = new Deriv; return b; }
BOOST_PYTHON_MODULE(testA) { class_<Base, Base_Wrap, boost::noncopyable>("Base", no_init);
def("createBase", createBase, return_value_policy<manage_new_object>()); }
This code won't compile, will it?
It seemed implied to me by the docs and some other emails that foo should not be defined in Base.
What implied that? Ideally Boost.Python shouldn't have any effect on the design of the classes that it wraps. Base_Wrap should only be used to dispatch virtual functions to Python with call_method.
I had done that in the past, but changed on this refactoring of the code. Although not demonstrated in this code, when I say plugin I mean a dynamic library/shared object that is loaded using dynlib. It actually provides the implementation of the factory.
Your code isn't demonstrating much at all, since it doesn't show an example of what you're trying to accomplish. Maybe someone else can help you; I have no clue what you're after, sorry! P.S. Did you try what I suggested in my previous reply? class_<Abstract, non_copyable>("Abstract", no_init) .def("pure_virtual_function1", &Abstract::pure_virtual_function1) .def("pure_virtual_function2", &Abstract::pure_virtual_function2) ... ; -- Dave Abrahams Boost Consulting www.boost-consulting.com
On Sat, 2003-07-26 at 13:31, David Abrahams wrote:
This code won't compile, will it?
It does.
Your code isn't demonstrating much at all, since it doesn't show an example of what you're trying to accomplish. Maybe someone else can help you; I have no clue what you're after, sorry!
P.S. Did you try what I suggested in my previous reply?
class_<Abstract, non_copyable>("Abstract", no_init) .def("pure_virtual_function1", &Abstract::pure_virtual_function1) .def("pure_virtual_function2", &Abstract::pure_virtual_function2) ... ;
Apologies for the unclear code, and the suggestion does work, so thanks. --temas
participants (2)
-
David Abrahams -
Thomas Muldowney