I want to make a plugin system with the capability to override a method at runtime.
Some answers say function pointers, but how about a defined function or class?
Like this:
class foo
{
public:
bar(int foobar);
}
Is there a way to get function pointer for that, or replace it?
BTW, hooking is not considered an answer because it's very platform specific and dangerous.
To make a plugin system you don't need to replace a method of a class at runtime.
You can replace what the method does by using polymorphism or any other way to configure an object.
Check out the answers to the following question: What's safe for a C++ plug-in system?
Runtime function "replacement" can be achieved with one of several techniques:
std::function
On which option is better is highly dependent on the intended use and target environments. For example; plugin systems could well make use of polymorphism (with the appropriate factories and possibly even combined with the template method pattern) whilst internal function routing could use std::function
.
These techniques wouldn't really "replace" any of the functions, but rather can be set up at runtime to route the function call as required.
Note I've focused on the C++ aspects of the question (it was tagged C and C++ but the sample code is C++).
While you can't directly replace a method, this can be solved with another layer of indirection.
#include <iostream>
#include <functional>
class Foo
{
private:
void default_bar(int value)
{
std::cout << "The default function called\n";
}
std::function<void(Foo*, int)> the_function = &Foo::default_bar;
public:
void replace_bar(std::function<void(Foo*, int)> new_func)
{
the_function = new_func;
}
void bar(int value)
{
the_function(this, value);
}
void baz(int value)
{
std::cout << "baz called\n";
}
};
void non_member(Foo* self, int value)
{
std::cout << "non-member called\n";
}
int main()
{
Foo f;
f.bar(2);
f.replace_bar(&Foo::baz);
f.bar(2);
f.replace_bar(non_member);
f.bar(2);
f.replace_bar([](Foo* self, int value){ std::cout << "Lambda called\n"; });
f.bar(2);
}
Currently this replaces the method of the instance. If you want to replace the method of a class, make the_function
static (even better, make it a static method returning a static variable to avoid static initialization order fiasco)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With