Coding static to instance method trampoline function with templates - c++

I'm trying to recode some rather ugly template coding.
For reference, the original is here: https://codereview.stackexchange.com/questions/69545/recode-c-c-trampoline-function-macros-using-templates
class Final : Base
{
void Foo(){...}
void Bar(){...}
static void init(){
// register_method populates a table of "extern C" function pointers.
register_method( "foo", & FooHandler );
register_method( "bar", & BarHandler );
}
:
// trampolines
static void FooHandler( void* pInstance ) {
Final* f = reinterpret_cast<Final*>(pInstance);
f->Foo();
}
static void BarHandler( void* pInstance ) {
Final* f = reinterpret_cast<Final*>(pInstance);
f->Bar();
}
}
My code interfaces with CPython (C library).
Python runtime sees "myInst.foo" , looks up "foo" in table and invokes:
Final::FooHandler( pointer_to_myInst );
(Note it is possible to typecast a static method to a C function pointer)
FooHandler trampolines to the Foo method of the correct instance of Final.
In reality, the handle is not so clean, and there are many methods each of which requires an identical handler (but with a distinct function address).
I am attempting to abstract the handler mechanism into a base class, something like this:
class Final : Base<Final>
{
void Foo(){...}
void Bar(){...}
static void init(){
// register_method populates a table of "extern C" function pointers.
register_method( "foo", & Foo, Handler< &Foo> );
register_method( "bar", & Bar, Handler< &Bar> );
}
:
}
class Base<Final>
{
typedef void (Final::*FuncSig)(void);
typedef void (Final::*HandlerSig)(void*); // takes 1 pvoid param
void register_method( std::string name, FuncSig meth, HandlerSig handler ) {
...
}
// generic trampoline
template< Sig sig>
static void Handler( void* pInstance ) {
Final* f = reinterpret_cast<Final*>(pInstance);
f ->* sig();
}
}
I'm currently getting stuck in compiler errors (http://ideone.com/vOtbcD), so I'm not even sure whether the technique is valid.
Is there some way to do this, or is this just one of those times where you really need macros?
For reference, the original is here: https://codereview.stackexchange.com/questions/69545/recode-c-c-trampoline-function-macros-using-templates
As can be seen, the original uses rather ugly macros.

register_method needs to be static if you're going to call it from the static init function.
Calling a member function through a member function pointer requires an additional set of parenthesis: (f->*sig)();
With those in place, your test case compiles in C++11 mode. That said, have you considered using std::function and std::bind to do this instead? Hard to tell what that would actually look like without knowing what register_method does, but it might wind up a bit cleaner.

The following code works on ideone (http://ideone.com/vOtbcD):
#include <iostream>
using namespace std;
#include <map>
template<typename T>
class Base
{
public:
typedef void (T::*PFunc)(void);
typedef void (*PHandler)(void*);
using method_map_t = map< string, PHandler >;
static method_map_t& methods( ) {
static method_map_t* map_of_methods{};
if( ! map_of_methods ) map_of_methods = new method_map_t;
return *map_of_methods;
}
static void register_method( string name, PHandler handler ) {
methods()[name] = handler;
}
// generic trampoline
template<PFunc sig>
static void Handler( void* pInstance ) {
T* f = reinterpret_cast<T*>(pInstance);
(f ->* sig)();
}
};
...
class Final : Base<Final>
{
public:
void Foo(){cout<<"got foo";}
void Bar(){cout<<"got bar";}
static void init(){
// register_method populates a table of "extern C" function pointers.
register_method( "foo", static_cast<PHandler>( &Handler<&Final::Foo> ) );
register_method( "bar", static_cast<PHandler>( &Handler<&Final::Bar> ) );
}
};
void InvokeFromC(void* inst, string name) {
Base<Final>::PHandler h = Base<Final>::methods()[name];
(*h)(inst);
}
int main() {
Final* f = new Final{};
f->init();
// simulate invoking from C
InvokeFromC( f, "foo" );
// your code goes here
return 0;
}
Note: (Eelis on IRC) gcc is known not to be able to resolve addresses of function template specializations passed to functions. You can work around it either by declaring separate variables for the function pointers, or using a dirty cast (or a nice cast like boost::implicit_cast)
I have put this code up for review at: https://codereview.stackexchange.com/questions/69876/static-to-instance-method-trampolining-with-templates

Related

Convert from modern C++11 function to raw function pointer

Let's suppose I have the following function interface:
void giveme(void (*p)());
That function simply accepts a pointer to a function with no return type and argument.
I'm wondering if exists a way (without change the interface) to pass a class method as parameter of that function.
I'll try to explain better with an example. I have a class, like:
class Foo {
public:
template<typename T>
void bar();
};
I want to pass bar<T> (of an addressable instance of the class) as parameter of the function giveme.
I thought to bind the method with an object, and obtain the function target.
Something like:
int main(int argc, char *argv[]) {
Foo foo;
std::function<void()> f = std::bind(&Foo::bar<int>, &foo);
giveme(f.target<void()>());
return 0;
}
It compiles, but obviously does not work because, from here:
TargetType shall match the target type, so that typeid(TargetType)==target_type(). Otherwise, the function always returns a null pointer.
So, if exists, what is a way to achieve it?
Here's one (very bad) idea:
Foo * foo_ptr; // maybe thread_local
void foo_call()
{
foo_ptr->bar<int>();
}
int main()
{
Foo foo;
foo_ptr = &foo;
give_me(&foo_call);
}
It's not pretty, but neither is your situation.
There's only one way I know of, and it's a terrible idea, and don't do this.
typedef void (*void_fn)();
struct stateful_void_fn_data = {
void_fn raw;
std::function<void()> actual;
std::atomic_bool in_use;
}
// a global array to hold your function bindings and such
extern stateful_void_fn_data stateful_functions[5];
// N stateless functions that defer to the correct global state
template<int n> void void_fn_impl() {stateful_functions[n].actual();}
extern stateful_void_fn_data stateful_functions[5] =
{{void_fn_impl<0>}, {void_fn_impl<1>}, {void_fn_impl<2>}, {void_fn_impl<3>}, {void_fn_impl<4>}};
// function to register a stateful and get a stateless back
void_fn allocate_void_fn(std::function<void()>&& f) {
for(int i=0; i<5; i++) {
if(stateful_functions[i].in_use.compare_exchange_weak(false, true)) {
stateful_functions[i].actual = std::move(f);
return stateful_functions[i].raw;
}
}
throw std::runtime_error("ran out of stateful functions :(");
}
// function to unregister
void free_void_fn(void_fn f) {
if (f == nullptr) return;
for(int i=0; i<5; i++) {
if (stateful_functions[i].raw == f) {
stateful_functions[i].in_use = false;
return;
}
}
throw std::runtime_error("unknown void function");
}
Basically, I generate 5 void() functions (void_fn_impl<N>), and each calls a function stored in one of the five a global array slots (stateful_functions[i].actual). Then, allocate_void_fn will store any std::function<void()> in the global array, and hand you the void() that calls that entry in the array. This function itself is stateless, because we've stored all the state in the global array. free_void_fn and in_use exist solely to make the functions reusable.
And of course, because RAII is good:
class hidden_state_void_fn {
void_fn raw;
public:
hidden_state_void_fn(std::function<void()>&& f)
:raw(allocate_void_fn(std::move(f)) {}
hidden_state_void_fn(const hidden_state_void_fn&& r) {
raw = r.raw;
r.raw = nullptr;
}
hidden_state_void_fn& operator=(const hidden_state_void_fn&& r) {
free_void_fn(raw);
raw = r.raw;
r.raw = nullptr;
}
~hidden_state_void_fn() {free_void_fn(raw);}
operator void_fn() {return raw;}
operator()() {raw();}
};
std::map<int,std::function<void()>> tasks;
template<int n>
struct task_wrapper{
static void f(){ if (tasks.count(n)) tasks[n](); }
task_wrapper(std::function<void()> fin){ tasks[n]=fin; }
~task_wrapper(){ tasks.erase(n); }
static std::shared_ptr< void(*)() > make(std::function<void()> fin){
auto self=std::make_shared<task_wrapper>(fin);
return { &f, fin };
}
};
A task_wrapper<N>::make(func) return a shared pointer to a stateless function pointer that will call the stateful func.
We can use the the usual techniques to create an array of K function pointers of signature shared_ptr<void(*)()>(*)(). Then we can have a shared_ptr<void(*)()> register_func( std::function<void()> ).
To find blanks, we can either do a linear search, or we could build a table of blanks. This could look like a traditional allocation/free "heap", or a range-tree of blanks, or whatever.
Another approach would be to literally create and save a DLL on the fly then load it and call the symbol. This could be done via hacks (have such a DLL and a known offset to modify, copy and write, then load and run) or by shipping a C++ compiler (or other compiler) with your code (!).

Get the name of a std::function

In the following toy-example, I would like to get the name of a function. The function itself was given as an std::function argument. Is it possible in C++ to get name of a std::function object?
void printName(std::function<void()> func){
//Need a function name()
std::cout << func.name();
}
void magic(){};
//somewhere in the code
printName(magic());
output: magic
Otherwise I would have to give the function's name as a second parameter.
No there isn't. Function names (like variable names) are compiled out so they are not visible at run-time.
Your best bet is to pass the name of the function (use a std::string or a const char*) as you've suggested yourself. (Alternatively you could base a solution on __func__ which was introduced in C++11.)
The answer is no, but you could make something like
template<class R, class... Args>
class NamedFunction
{
public:
std::string name;
std::function<R(Args...)> func;
NamedFunction(std::string pname, std::function<R(Args...)> pfunc) : name(pname), func(pfunc)
{}
R operator()(Args&&... a)
{
return func(std::forward<Args>(a)...);
}
};
And then define a preprocessor
#define NAMED_FUNCTION(var, type, x) NamedFunction<type> var(#x,x)
...
NAMED_FUNCTION(f, void(), magic);
Given a std::function it has a member function called target_type which returns the typeid of the stored function object. That means you can do
void printName(std::function<void()> func){
//Need a function name()
std::cout << func.target_type().name();
}
This returns an implementation-defined string that is unique for each type. With Visual Studio, this string is human-readable already. With gcc (or maybe it's glibc? I don't know who takes care of what in detail) you need to use abi::__cxa_demangle after including <cxxabi.h> to get a human-readable version of the type name.
EDIT
As Matthieu M. pointed out, given a function pointer, the type returned by this will just be the function's signature. For example:
int function(){return 0;}
printName(function);
This will output (assuming you demangled if necessary) int (*)() which is not the function's name.
This method will work with classes though:
struct Function
{
int operator()(){return 0;}
};
printName(Function{});
This will print Function as desired, but then doesn't work for function pointers.
You could also have your function with a string parameter for the name and then use a macro to call it
void _printName(std::function<void()> func, const std::string& funcName){
std::cout << funcName;
}
#define printName(f) _printName(f, #f)
void magic(){};
//somewhere in the code
printName(magic);
See example
Maintain your own map from function pointer to name.
template<class Sig>
std::map<Sig*, const char*>& name_map() {
static std::map<Sig*, const char*> r;
return r;
}
struct register_name_t {
template<class Sig>
register_name_t( Sig* sig, const char* name ) {
name_map()[sig]=name;
}
};
#define TO_STRING(A) #A
#define REGISTER_NAME(FUNC) \
register_name_t FUNC ## _register_helper_() { \
static register_name_t _{ FUNC, TO_STRING(FUNC) }; \
return _; \
} \
static auto FUNC ## _registered_ = FUNC ## _register_helper_()
Simply do REGISTER_NAME(magic); to register the name magic to the function magic. This should be done at file scope, either in a header or a cpp file.
Now we check if the std::function has a function pointer matching its signature stored inside of it. If so, we look it up in our name_map, and return the name if we find it:
template<class Sig>
std::string get_function_name( std::function<Sig> const& f ) {
auto* ptr = f.target<Sig*>();
if (!ptr) return {};
auto it = name_map().find(ptr);
if (it == name_map().end()) return {};
return it->second;
}
this is generally a bad idea.
I think the simplest solution is to use typeid(fun).name() for example like this:
#include <typeinfo>
#include <stdio.h>
void foobar( void )
{
}
int main()
{
printf( "%s\n", typeid( foobar ).name() );
return 0;
}
Now, it have a lot of drawbacks, and I would not recommend using that.
First of all, IIRC it shows the symbol of the function, not the name you used in source code.
Also, the name will change from compiler to compiler.
And finally, RTTI is slow.
[edit]
Also, I'm not sure how it works with std::function. Never used that, honestly.

Vector of pointer to member functions

I'm trying to write a program which creates a class that contains vector of pointers to member functions, with add() and remove() member functions.
The code I wrote is -
#include <iostream>
#include <vector>
using namespace std;
typedef void(*classFuncPtr)();
class FunctionVectors
{
private:
vector<classFuncPtr> FunctionPointerVector;
public:
FunctionVectors(){}
void add(classFuncPtr funcPtr);
void remove(int index);
void run();
void a(){cout<<"a: Why are you calling me?"<<endl;}
};
void FunctionVectors::add(classFuncPtr funcPtr)
{
FunctionPointerVector.push_back(funcPtr);
}
void FunctionVectors::remove(int index)
{
FunctionPointerVector.erase(FunctionPointerVector.begin() + index);
}
int main()
{
FunctionVectors f;
classFuncPtr fv = &(classFuncPtr)FunctionVectors::a; // error here
f.add(fv);
f.run();
return 0;
}
But, it is showing error in line# 32 -
error C2440: 'type cast' : cannot convert from 'void (__thiscall FunctionVectors::* )(void)' to 'classFuncPtr'
Please, tell me how should I modify it to work properly.
typedef void(*classFuncPtr)();
This is not a pointer to method, but a pointer to function. Method differs from function, because it's being called in a context: requires this to work correctly.
Keep in mind, that in C++ you are only able to create vector of pointers to a method of specific class. So you won't be able to keep pointers to two methods of different classes in that vector.
The solution - as suggested in comments - is to use std::function or boost::function and possibly C++11 lambdas, because they provide a lot more flexibility than simple pointer-to-members.
If you want to implement an event mechanism, consider also using functors instead of methods:
Create base class for event handler:
class MyEventHandler
{
public:
virtual void operator()(void * sender, int data) = 0;
}
Create simple vector of these:
std::vector<MyEventHandler *> MyEvent;
Create specific handlers in your classes:
class MyClass
{
private:
class SpecificEventHandler : MyEventHandler
{
public:
void operator()(void * sender, int data)
{
std::cout << "Event handled!";
}
}
public:
SpecificEventHandler Handler;
MyClass()
{
}
}
Hook the handler to your event:
MyEvent.push_back(&(myClassInstance.Handler));
Code written from memory, may not compile, but you should get the idea.
std::function< void() >
looks like the signature you are looking for. If it isn't available in your version of C++ but you can use boost, then you fill find it in boost. Look up documentation for appropriate header, for std, for function.
To create one for a member function, you need to bind it, and to bind it to FunctionVectors::a() you will need an instance of a FunctionVectors to call it on.
In your example, I will make the typedef for you
typedef std::function< void() > classFuncPtr; // in reality a badly named typedef
int main()
{
FunctionVectors f;
classFuncPtr fv = std::bind( &FunctionVectors::a, f );
}
alternatively if you really have C++11 with lambdas you can do
classFuncPtr = [ f ]() { f.a() );
In your case I reckon you don't really want a free function, you always want a member function of your class you want.
typedef void (*FunctionVectors::classFuncPtr )();
and you would use
(this->*func)();
to invoke it

How to execute unary function objects of different parameter type in sequence?

I'm designing a mechanism that will execute a set of unary function objects in sequence. These function objects are assigned during runtime, and the problem is: the parameter type of these function objects are different.
What I want to do is something like this:
class command_sequence {
private:
/* some kind of container */
public:
void add( FUNC_OBJ &func, PARAM val );
void run(void);
};
class check_temperature {
public:
void operator() (int celsius) {
if(celsius > 26) {
cooler.switch_on();
}
}
};
class log_usage {
public:
void operator() (std::string username) {
username.append(" logged in");
syslog(LOG_NOTICE,username.c_str());
}
};
command_sequence sequence;
log_usage logger;
check_temperature checker;
sequence.add(logger, std::string("administrator"));
sequence.add(checker, lobbyMeter.read_temperature());
sequence.add(logger, std::string("lecture"));
sequence.add(checker, classroomMeter.read_temperature());
sequence.run();
If I'm writing C code, I have no choice but callback function pointer that takes void* as parameter. But I'm now working with C++, there should be an elegant way to deal with it.
The best way I can think now is declaring a template class that virtually inherit from a abstract wrapper class :
class command_sequence {
private:
class runner {
public:
virtual void execute(void) = 0;
};
template <class FUNC, typename T> class func_pair : public runner {
private:
FUNC &func;
T param;
public:
func_pair(FUNC &f, const T &t) : func(f),param(t) { }
void execute(void) {
func(param);
}
};
std::vector<runner*> funcQueue;
public:
template <class FUNC, typename T> void add(FUNC &obj, const T &t) {
funcQueue.push_back( new func_pair<FUNC,T>(obj,t) );
}
void run(void) {
std::vector<runner*>::iterator itr=funcQueue.begin();
for(;itr!=funcQueue.end();++itr) {
(*itr)->execute();
delete (*itr);
}
}
};
This approach can fit my needs, but it would allocate and release template_pair for each entry. I've no idea whether this would cause memory fragment, since this procedure will be called quite frequently during the process.
Is there any better way to do this ?
Do you really need to pass a function object and its argument separately? I'd use boost::bind, in this case it could look like the following:
void check_temperature( int celsius )
{
if(celsius > 26) {
cooler.switch_on();
}
};
void log_usage( std::string username )
{
username.append(" logged in");
syslog(LOG_NOTICE,username.c_str());
};
// keep actions
typedef std::vector< boost::function<void()> > func_arr_t;
func_arr_t actions;
actions.push_back( boost::bind( &log_usage, "administrator" ) );
actions.push_back( boost::bind( &check_temperature, lobbyMeter.read_temperature() ) );
actions.push_back( boost::bind( &log_usage, "lecture" ) );
actions.push_back( boost::bind( &check_temperature, classroomMeter.read_temperature() ) );
// run all
for ( func_arr_t::const_iterator it = actions.begin(); it != actions.end(); ++it )
(*it)();
In this case command_sequence will just keep an array of the function objects.
Since it appears that the argument to the unary function is fixed at the time you add it to the sequence, you could make your sequence accept zero-argument function objects using boost::function, then boost::bind the required parameter, e.g.
class command_sequence {
public:
void add( boost::function<void(void)> functor );
};
/* ... as before ... */
log_usage logger;
check_temperature checker;
sequence.add( boost::bind<void>(logger, "administrator") );
sequence.add( boost::bind<void>(checker, lobbymeter.read_temperature()) );
Note that you have to specify <void> as a template parameter to the boost::bind call since it can't deduce the return type of the function object automatically. Alternatively, you can expose a public typedef called result_type in the class definition which avoids this, i.e.
class log_usage
{
public:
typedef void result_type;
void operator() (const std::string& message)
{
// do stuff ...
}
};
/* ... */
sequence.add(boost::bind(logger, "blah")); // will now compile

C++ variable number of arguments

I need to define a virtual function that can take variable number of arguments, problem is c style ellipses does not work for non pod types, I have limited amount of memory (2KB) so i am trying to avoid allocating temp object just to pass to the function, all arguments will be of the same type (a custom shared pointer), I also don't have access to stl or boost. Is there a c++ trick that would allow me to call a func with variable arguments?
Assuming your argument types are of class Arg, you can try this:
class ArgUser {
public:
// syntactic sugar:
void method() { // nullary
doMethod();
}
void method( const Arg & a1 ) { // unary
doMethod( &a1 );
}
void method( const Arg & a1, const Arg & a2 ) { // binary
doMethod( &a1, &a2 );
}
// and so on, until max arity
private:
// actual virtual function:
virtual void doMethod( const Arg * a1=0, const Arg * a2=0 /*etc, until max arity */ ) = 0;
};
This solution has the following properties:
It uses the NVI idiom
It uses pointers because they will not cause temporaries to be created, even for unused default arguments.
It encapsulates the ugly pointer juggling in (inline) wrapper methods.
An alternative solution (that may or may not be more efficient) is this:
class AltArgUser {
public:
// syntactic sugar:
void method() { // nullary
doMethod( 0, 0 );
}
void method( const Arg & a1 ) { // unary
doMethod( &&a1, 1 );
}
void method( const Arg & a1, const Arg & a2 ) { // binary
const Arg * args[] = { &a1, &a2 };
doMethod( args, 2 );
}
// and so on, until max arity
private:
// actual virtual function:
virtual void doMethod( const Arg * args[], size_t numArgs ) = 0;
};
To decide which one to use, you need to study the assembler generated for each method on your particular platform. Whatever you choose, you should definitely keep the wrapper functions.
Define the function to take a pointer to an array of parameters and a parameter for the size of the array.
Also, if you do not want to hard code a fixed sized array you could use alloca to allocate the storage on the stack and not worry about a trip to the heap or calling free.
Pointers to shared pointers are PODs, could you change the prototype to use the memory location of each argument? Like this (not tested):
shared_ptr arg1;
shared_ptr arg2;
ClassWithVirtualFunction c;
c.yourVirtualFunction(&arg1, &arg2, NULL);
ClassWithVirtualFunction
{
virtual void yourVirtualFunction(shared_ptr* first, ...)
{
va_list marker;
va_start( marker, first );
shared_ptr* current=first;
while (current != NULL)
{
/* do stuff with *current */
current = va_arg( marker, shared_ptr* );
}
va_end(marker);
}
}
You can use a fixed array that is actually faster and takes less space than variable number of arguments. Because variable number of arguments does a lot of checks and safety.
mytype arr[3];
arr[0] = a;
// etc
myfunction(arr, 3);
Perhaps if you already have your own custom pointer type, you could define your own basic linked list class (this is C++ after all), with the last "pointer to next" being NULL to indicate the end of the variable number of args.
Something like this:
class MyPointer
{
// Whatever you have/want
};
class MyArgs
{
static int nargs; // Static class variable for total number of args
MyPointer* data;
MyArgs* next;
public:
MyArgs(int nargs)
{
// Some funky constructor to create required number of args...
}
MyPointer* operator[](int at)
{
// Nice overloaded operator for you to get at data
}
};
class PlanToDoStuff
{
public:
virtual void foobar(MyArgs)=0;
};
class ActuallyDoStuff: public PlanToDoStuff
{
public:
void foobar(MyArgs)
{
// Do stuff with args...
}
};
int main()
{
MyArgs args(3);
ActuallyDoStuff dosomething;
dosomething.foobar(args);
}