How to cast void pointers to function pointers - c++

I am trying to write a class that will be appended with some function pointers.
This pointers will be called from another method of this class. I will be storing the function pointers on a void* vector so anything can go on a single vector, instead of a different vector for each type.
I intend to declare a different AppendCallback methods for any different function I need to call from inside the class, for example:
void MyClass:AppendCallback(void (*Callback)())
{
_CallbackVector.push_back((void*)Callback);
_IdVector.push_back(VoidID);
}
void MyClass:AppendCallback(void (*Callback)(uint32_t));
void MyClass:AppendCallback(void (*MyOtherClass::Callback)());
void MyClass:AppendCallback(void (*MyOtherClass::Callback)(uint32_t));
There will be a second vector that only contains identifiers to know what the void* points to, this is going to be assigned also on the AppendCallback Methods.
How can I cast the void pointer again to the function pointers for calling those functions?
Maybe something like this?
void MyClass::Service(uint32_t x)
{
for(uint i = 0; i < _CallbackVector.size(); i++)
{
switch(_IdVector[i])
{
case VoidID: void(*_CallbackVector[i]()); break;
case Uint32ID: void(*_CallbackVector[i](x)); break;
}
}
}
Edit:
Is this a proper way of casting from a void* to a function pointer?

That's not allowed in C++:
Converting a void* to a function pointer directly is not allowed (should not compile using any of the casts) in C++98/03. It is conditionally supported in C++0x (an implementation may choose to define the behavior and if it does define it then it must do what the standard says it should do. A void*, as defined by the C++98/03 standard, was meant to point to objects and not to contain function pointers or member pointers.
And again:
You can't.
You can cast a data pointer to void* and then back to the same pointer type you have started with. std::function is not a pointer type, so the cast is statically invalid, and it's not the same thing you have started with. You have started with a .target of type void()() but it's not a data pointer, it's a function pointer, so casting it to void and back is implementation-defined.
In your specific situation, you could try something like this:
class PointerToFunction {
};
template <typename Type>
class PointerToFunctionType : public PointerToFunction, std::function<Type> {
public:
using std::function<Type>::function; // I think this is the right syntax for this trick: https://softwareengineering.stackexchange.com/a/197901/342247
};
// Now, we can do this:
std::vector<PointerToType*> _CallbackVector;
Basically, we're using an inheritance trick similar to how boost::any/std::any (since C++17) is implemented to store any std::function in a pointer. The only issue is knowing how to convert it back. Doing this properly would depend on how you expected to convert that void* back to begin with (i.e., knowing its type), so I'll leave that part up to you.

Related

Shared pointer inheritance without explicitly casting first

So, I am trying to do something like this
template <typename T>
void call(std::shared_ptr<Base<T>> b) {
}
int main() {
std::shared_ptr<Derived<int>> d = std::make_shared<Derived<int>>();
call(d);
}
It cant resolve the inheritance because they are shared pointers. Ideally I don't want to use static_pointer_cast or something like that in main so I was looking for maybe a different way to cast it so that the user in main can still call the same function but not have to worry about casting.
My second approach was to use raw pointers so I tried something like this:
template <typename T>
void call(Base<T> * b) {
std::shared_ptr<Base<T>> obj(b);
}
int main() {
std::shared_ptr<Derived<int>> d = std::make_shared<Derived<int>>();
call(d.get());
}
Since Base is an abstract class I can't use make_shared so I have to do it this way to my knowledge but the problem then becomes that as soon as the call function's scope ends it deletes the pointer resulting in a double free error since the shared ptr in main also tries to delete this.
Are there any suggestions for something to try?
First, it is a bad practice to use smart pointers wherever the ownership is not needed. In your case the main function owns the pointer, and there is no way the object is destroyed while the call function is being executed. So you may pass a raw pointer without problems (and that is even better because the interface doesn't require more than it needs). This however may not be true in case of multithreaded environment or if the call function has side effects storing the pointer (e.g. that is actually a set method if a class). In this case shared_ptr should be used indeed.
Next, you may create a shared_ptr<Base> initializing it with a pointer to Derived. You even don't need to have virtual destructor for deleting the object: shared_ptr knows the actual type:
{
std::shared_ptr<Base> d = std::make_shared<Derived>();
// Ok to delete
}
Finally, there is no problem in casting shared_ptr<Derived> to shared_ptr<Base>. That is another instance of a shared pointer that points to the same counter.

How do I pass a std::function object to a function taking a function pointer?

I am trying to interface with a library written in c, that uses this familiar pattern:
void some_c_handler(void(*func)(void*), void* data);
Now, I want to write a C++ wrapper for this function that looks like this:
void my_new_cpp_handler(std::function<void()>&& func)
{
void (*p)() = foo(func);
void* data = bar(func);
some_c_handler(p, data);
}
Both some_c_handler and my_new_cpp_handler are solving the same problem; they're taking in some kind of function along with some state. But the latter is preferred in that it abstracts much of the implementation details from the user, and allows for simply passing in a lambda object.
So my_new_cpp_handler should take the func parameter it is given, convert it to a function pointer and pass its state on to data.
I don't know enough about the standard, or the implementation of std::function to know if this is even a reasonable request. Can foo and bar exist?
To put it differently, what I want is to be able to pass a stateful function to a c callback handler without having to manually instantiate my own struct type to pass along with it. Obviously std::function has already done this for us, so I'd love to be able to separate the function pointer from the state somehow and pass it onto the c-style handler. Is this possible?
Is this possible?
No.
You can wrap a C-style callback into an std::function<>..., and the compiler will emit code to extract the data and the handler and call it. However, the exact code to do so will depend on the compiler, the ABI and the standard C++ library being used. You can't magically reconstruct that code given only the std::function wrapper.
Further, an arbitrary std::function... (or a lambda) may wrap code other than a call to C-style handler. It should be obvious that applying the "magically reconstructed" code to extract C-style handler from such an instance of std::function... can't possibly succeed.
P.S.
To put it differently, what I want is to be able to pass a stateful function to a c callback handler without having to manually instantiate my own struct type to pass along with it. Obviously std::function has already done this for us
So why don't you just use what std::function has already done for you:
void my_new_cpp_handler(std::function<void()>&& func)
{
func(); // calls some_c_handler(p, data) IFF that is what "func" encodes.
}
If you were to carefully review the documentation for this library, you will find that the
void some_c_handler(void(*func)(void*), void* data);
Invokes func, passing it the data argument.
This is a very common design pattern for C libraries that take a callback function. In addition to the callback function, they also take an additional opaque pointer that is not interpreted by the library, but is blindly forwarded to the func. In other words, the C library invokes
func(data);
You can use this from C++ code to pass an ordinary pointer to any class.
This includes std::function, too.
The trick is that in most situations it will be necessary to use new:
auto *pointer=new std::function< function_type >...
The end result is a pointer that can be passed to the C library, together with a pointer to a "trampoline function":
some_c_handler(&cpp_trampoline, reinterpret_cast<void *>(pointer));
And the trampoline recasts the opaque pointer:
void cpp_trampoline(void *pointer)
{
auto real_pointer=reinterpret_cast<std::function< ... >*>(pointer);
// At this point, you have a pointer to the std::function here.
// Do with it as you wish.
The only detail you will need to square away here is to figure out the correct scope for the dynamically-allocated function pointer, in order to avoid memory leaks.
You can make a wrapper function whose purpose is to simply execute the std::function callback.
void some_c_handler(void(*)(void*), void*) {}
void std_function_caller(void* fn) {
(*static_cast<std::function<void()>*>(fn))();
};
auto make_std_function_caller(std::function<void()>& fn) {
return std::make_pair(std_function_caller, static_cast<void*>(&fn));
}
void my_new_cpp_handler(std::function<void()>&& func) {
const auto p = make_std_function_caller(func);
some_c_handler(p.first, p.second);
}
According to this link, the std::function object has no accessible member that can provide raw access to the pointer. You should probably define a struct that contains a pointer to the function pointer and the object, and a constructor wrapper that stores the pointer's address to the struct before the construction of your std::struct, so as to assign the address stored in the pointer it points to to your C handler's parameter.

about void pointer, classes and casting

I have c++ experience for about a year or two but I code the same way I code in Java (simple oop stuff). Now I have this sample code which I don't understand. (it's quite big so I tried to make it shorter, I hope it's clear enough for you guys)
//in .h file
typedef void*(*AnimalCreation)();
//in .cpp
void foo(void* p)
{
AnimalCreation ac = (AnimalCreation)p;
Animal* current_animal = reinterpret_cast<Animal*>(ac());
current_animal->init();
}
//somewhere in another class foo is called
Dog* dog = new Dog(); //Dog is a subclass of Animal
foo((void*)&dog)
What is the purpose of AnimalCreation?
And what's the difference between that and
typedef void(*AnimalCreation)();`//without asterisk after void
What's happening inside foo?
If the expected argument foo receives is always a subclass of Animal why does the programmer need to implement it like in the above and not just foo(Animal*)?
Thanks.
typedef void(*AnimalCreation)();
this declares "AnimalCreation" to be used as type-alias for a pointer to a function which doesn't return any value, while this
typedef void*(*AnimalCreation)();
declares it to be used as a type-alias for a pointer to a function which returns a void pointer, i.e. an address to something you don't know its type.
Inside foo you're receiving such a "generic address" and you're C-casting(potentially unsafe, checked at runtime) it to a function pointer. This is at your own risk: you don't know what that received address is pointing to. And after that you're calling the function and receiving another void pointer which you reinterpret (dangerous) as an Animal object. And then you use it.
A function pointer cannot be a subclass of anything so I don't think the argument in that code is an Animal subclass... rather the subclass to the Animal class is the object returned by that function. Assuming that is also a polymorphic class, you will then be able to call its methods with the virtual inheritance rules. If you intend to check the pointer received by the function call and you're unsure whether it is a subclass of the Animal class, you'd rather be using dynamic_cast.
As a sidenote: converting between function pointers and void* is a bad practice in C++ since you lose valuable type information.
The typedef line is AnimalCreation being defined as a function pointer type
Function foo takes in a void * argument which it casts into an AnimalCreation type (i.e. into the function pointer type). It can then invoke the function via the function pointer. This invocation returns a void * (as per the typedef - the part before the firts bracket is the return type, hence void*) which is then casted to an Animal* by reinterpret_cast.
If you removed the asterisk from the typdef - it would still declare a function pointer type, but now the return value would be void instead of void * (i.e. nothing returned, rather than a pointer). You could still invoke the function via the function pointer, but it would not return anything.
All in all, this is a nice little function pointer tutorial.
EDIT : the big picture of what this code seems to be doing - this is one way of implementing a 'Factory Pattern' in C++ - abstracting the creation of an object, and returning a polymorphic base class pointer to a derived class. Casting between void * and function pointers and reinterpret_cast is not the nicest way to achieve this, for alternatives you could look here
First off, this is quite ugly C-style code.
typedef void*(*AnimalCreation)();
To interpret this, follow the general rule of C & C++ declaration reading: if you type the declaration as an expression, you'll get its type.
*AnimalCreation This means AnimalCreation is a pointer
(*AnimalCreation)() This means *AnimalCreation is a function taking no arguments, so AnimalCreation is a pointer to function taking no arguments
void *(*AnimalCreation)() This means (*AnimalCreation)() is a void* (= pointer to void), so AnimalCreation is a pointer to a function which takes no arguments and returns a void*.
If it was just typedef void (*AnimalCreation)();, it would be a pointer to a function taking no arguments and returning no value (i.e. returning void).
Now, foo().
That takes a void* (pointer to anything) and interprets it as AnimalCreation - as a pointer to function taking no arguments and returning a void*. If the argument passed to foo was actually of that type, all is well. If something else is passed in, the program will exhibit Undefined Behaviour, which means anything can happen. It would most likely crash, as it could be trying to interpret data as code, for example.
foo() calls that function passed in, which returns a void*. foo() then interprets that as a pointer to Animal. If that's what the function actually returned, great. If not, Undefined Behaviour again.
Finally, the call you're showing will force the Undefined Behaviour to happen, because it's passing in the address of a pointer to an object. But, as stated above, foo() will interpret that as the address of a function, and try to call that function. Hilarity ensues.
To summarize, such code is bad and its author should feel bad. The only place you'd expect to see such code is interoperability with a C-style external library, and in such case it should be extremely well documented.

Casting from any

I'm packing some classes into ptr_map with any typed value.
class EventManager
{
ptr_map<string, any> mSomeMap;
public:
typedef signals2::signal<void (int someSignature)> KeyEvent;
EventManager()
{
mSomeMap["KeyPressed"] = new any(new KeyEvent());
}
};
Now I want to restore my signal object from any. Here is a special function for this:
template<typename EventType>
EventType *get(const string &signalName)
{
try {
return any_cast<EventType*>(mSomeMap[signalName]);
} catch(bad_any_cast &e){}
}
As you could remember, the boost's signals are noncopyable so I can store only pointers and my function should return pointers too.
Now sample usage:
evManager.get<EventManager::KeyEvent>("KeyPressed");
Here I get segfault. I checked the types of each objects in the get function:
typeid(EventType).name()
→ N5boost8signals26signalIFvRN2sf5Event8KeyEventEENS0_19optional_last_valueIvEEiSt4lessIiENS_8functionIS6_EENSB_IFvRKNS0_10connectionES5_EEENS0_5mutexEEE
mSignalAssociation[signalName].type().name()
→ N10__cxxabiv119__pointer_type_infoE
What's wrong is there? The segfault at line with casting. Any object should consist of inserted type or not? Why it doesn't want to cast.
ptr_map<string, any> mSomeMap;
...
mSomeMap["KeyPressed"] = new any(new KeyEvent());
Do you realize what happens here? First, you create a KeyEvent object dynamically which results in a pointer. Then this pointer is wrapped into an any-object which is also dynamically created which also returns a pointer which is then again wrapped in another any object implicitly by the assignment.
Also, for extracting the right value from an any object you need to know the exact type. So, for example, if you pack a Derived-pointer into an any object, you won't be able to access it via an any_cast<Base*> because Base* and Derived* are different types in terms of the std::type_info objects boost::any uses to keep track of types. boost::any just doesn't know how to convert the packed Derived-pointer to your Base-pointer.
Is there a special reason why you wrap so many things in any-objects including pointers to any-objects? Wouldn't it make sense to use something like a ptr_map<KeyType,BaseType>? You know that if you pack a pointer into an any object that you still need to delete the pointees yourself, right? The any-object is not going to do this for you.

C++ Comparing Member Function Pointers

In C++, is it possible to define a sort order for pointers to member functions? It seems that the operator< is undefined. Also, it's illegal to cast to void*.
class A
{
public:
void Test1(){}
void Test2(){}
};
int main()
{
void (A::* const one)() = &A::Test1;
void (A::* const two)() = &A::Test2;
bool equal = one == two; //Equality works fine.
bool less = one < two; //Less than doesn't.
return 0;
}
Thanks!
Function pointers are not relationally comparable in C++. Equality comparisons are supported, except for situations when at least one of the pointers actually points to a virtual member function (in which case the result is unspecified).
Of course, you can always introduce an ordering by implementing a comparison predicate and comparing the pointers explicitly (won't look too elegant though, since you can only use equality comparisons). Other possible solutions would cross into the territory of the various implementation-specific "hacks".
Member function pointers are not actual pointers. You should look at them as opaque structs. What does a method pointer contain:
struct method_pointer {
bool method_is_virtual;
union {
unsigned vtable_offset; // for a virtual function, need the vtable entry
void* function_pointer; // otherwise need the pointer to the concrete method
}
};
If you could cast this to void* (you can't) all you would have is a pointer the the struct, not a pointer to code. That's why operator<() is undefined as well since the value of the struct's pointer is just where ever it happens to be in memory.
In addition to that, what are you sorting by?