Reputation:
ignore this, i thought of a workaround involving header generation. It isnt the nicest solution but it works. This question is to weird to understand. Basically i want to call a virtual function that hasnt been declared in the lib or dll and use it as normal (but have it not implemented/empty func).
I have an abstract base class in my library. All my plugins inherit from it, the user plugin inherits from this class and his application uses this class as a plugin pointer. I want that user to be able to extend the class and add his functions. The problem is, I am sure if he adds a virtual function and try to call it, the code will crash due to my objects not having the extra data in its vtable. How can I work around that? I thought of inheriting it but that would lead to ugly problems when a 3rd user comes to play. I dont want him to typecast to send the extended functions.
I was thinking of a msg function like intptr_t sendMsg(enum msgName, void* argv); But that removes the safty and I'd need to typecast everything. Whats the best solution for this? I would much rather use vtables then use a sendMsg function. How can I work around this?
Upvotes: 0
Views: 402
Reputation: 264381
I am not 100% sure I see the problem.
If the user1 derived type extends your base class (with more virtual methods) then that should be fine (of course your code will never know or understand these new methods but presumably you would not be calling them:
class B
{
virtual void doStuff() { /* Nothing */}
};
// User 1 version:
class U1: public B
{
virtual void doStuff()
{
this->doA();
this->doB();
}
virtual void doA() {}
virtual void doB() {}
};
// User 2 version can extend it differently.
Note:
If you are worried by slicing because you are storing objects in a vector that is a slightly different problem.
std::vector<B> objs;
objs.push_back(U1());
std::for_each(objs.begin(),objs.end(),std::mem_fun_ref(&B::doStuff));
Here the problem is that a user defined type U1 can not be copied into the vector because the vector holds only B objects. This slices off the extra data held in U1.
The solution to this problem is that you need to hold pointers in the vector. This of course leads to other problems with exception safety. So boost has the ptr_vector<> container to hold objects correctly but still let them be used like objects.
#include <boost/ptr_container/ptr_vector.hpp>
......
boost::ptr_vector<B> objs;
objs.push_back(new U1());
std::for_each(objs.begin(),objs.end(),std::mem_fun_ref(&B::doStuff));
Upvotes: 1
Reputation: 18984
Are you asking if you can add virtual functions to the base class without recompiling? The short answer to that is "no". The long answer is in your question, you'd have to provide some kind of generic "call_func" interface that would allow you to call functions "dynamically".
Upvotes: 1
Reputation: 11309
I think you can use register and callback mechanism
Your plugin can provide Abstract base class "Base" and function
Register(Base *);
Now client can call plugin Register function
Register(b);
where b is defined as
Base *b = new Derived;
where Derived is new class derived from Base
Upvotes: 1