Event handling using union hack c++ - c++

I have hot two classes. Assume that one of them is an Image and the other is a Page. The Image object receives an OnPointerPressed event and When it happens I would like to call a function form the Page calss. The problem is that this function is not defined until I pass the address of the member function to the image using union hack. When this method is called from the Image class it works fine but inside the method I can't see the Page Object and its members.
MainPage::MainPage(void)
{
//.......
image1->OnPointerPressedHandler->add(&MainPage::imageMousePressed);
}
void MainPage::imageMousePressed(STObject* sender, STPointerEventArg * args)
{
void * dsda = this; //the address of this is something wierd
pres = true;
}
Can anybody help a little?
template<class T>
void add(T const & x)
{
union hlp_t{
void * v_ptr;
T t;
};
hlp_t a;
a.t = x;
functions->addLast(a.v_ptr);
}
template<class ARG>
void trigger(SENDERTYPE sender, ARG arg)
{
STLinkedListIterator<void *>* it = functions->createIteator();
if(it != nullptr)
{
do
{
void (*callback)(SENDERTYPE,ARG) =static_cast<void (*)(SENDERTYPE,ARG)>(it->getData());
callback(sender,arg);
/*
void * myVoid = it->getData();
__asm
{
push [arg];
push [sender];
call [myVoid];
}
*/
it->next();
}while(!it->EOL());
}
}

In both the assembly language version and the non-assembly language version of your code you are calling the member function incorrectly. There are specific requirements for member functions that do not apply to calling a free function (and static member functions) which is exactly what both versions of your code are doing. When calling non-static member functions the this pointer is implicitly passed as the first parameter. This can be done by either pushing the pointer value onto the stack, placing it in a register, or both - it really depends on how the compiler generates the calling code.
The current version of your code attempts to call the member function as if it was a free function but passes the object pointer on the stack. This is a very bad idea and is the reason why the value of this is incorrect. It also may not work as you expect if ARG is an object being passed by value instead of by reference or pointer. This is because the entire object needs to be copied onto the stack - don't even try doing this yourself. Instead you should use the features provided by the language that are specifically intended to allow you to call member functions by pointer.
The syntax for a pointer to member function is returntype (ClassType::*)(parameters). By using the correct syntax you can rely on the compiler to tell you when you use it incorrectly instead of trying to hunt down obscure bugs like you are currently doing. Not only should you use this when calling the member function but you should use it to store the pointer in your list. VC++ allows you to convert a function pointer to a void pointer but this is a Microsoft extension to the language and is not standard C++. I recommend you avoid the void whenever possible.
The one change you will need to make is how you are calling the member function. This is different than using a pointer to a free function and the following shows the correct syntax.
(objectpointer->*functionpointer)(arguments);
The extra set of parenthesis is required due to operator precedence and the ->* is the "pointer to member" operator. The code below shows the changes you will need to make to your code to correctly call the member function.
template<class ARG>
void trigger(STObject* sender, ARG arg)
{
STLinkedListIterator<void *>* it = functions->createIteator();
if(it != nullptr)
{
do
{
// cast to a pointer to member function so the compiler knows
// the correct type of the function call.
void (STObject::*callback)(ARG)
= static_cast<void (STObject::*)(ARG)>(it->getData());
// call it using the correct syntax and let the compiler
// handle all the gory details.
(sender->*callback)(arg);
it->next();
}while(!it->EOL());
}
}
You can make this more generic by adding an additional template parameter to specify the type of the target object.
template<class SENDER, class ARG>
void trigger(SENDER* sender, ARG arg)
{
STLinkedListIterator<void *>* it = functions->createIteator();
if(it != nullptr)
{
do
{
void (SENDER::*callback)(ARG)
= static_cast<void (SENDER::*)(ARG)>(it->getData());
(sender->*callback)(arg);
it->next();
}while(!it->EOL());
}
}
.
As a side note the function add() contains undefined behavior. From $9.5/1 of the C++ Language Standard
In a union, at most one of the data members can be active at any time, that is, the value of at most one of the data members can be stored in a union at any time.
In add() you set the value of t then read the value of v_ptr.

You need to pass in the 'this' pointer as well to make this work, otherwise it would instantiate a separate instance of the class:
You have to modify the imageMousePressed like this:
// add in a void* argument
void MainPage::imageMousePressed(STObject* sender, STPointerEventArg * args, void* mainPageObject)
{
MainPage* dsda = (MainPage*) mainPageObject; // now, you should have a pointer to the valid object
pres = true;
}
Now, this would mean the add function of OnPointerPressedHandler should also be modified to accomodate this:
image1->OnPointerPressedHandler->add(&MainPage::imageMousePressed, this);
And internally it should pass call the pointed function passing the 'this' value. The reason this does not work now, if the function is instantiated like a static function which would then be a part of a new object, so the state of your old object would not be preserved.
PS: You should paste more code to give a better idea to folks who answer this

Related

How to cast void pointers to function pointers

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.

Pass std::function to std::set_terminate? [duplicate]

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.

Passing a variable to a function which takes a smart pointer as a parameter, without that variable being a smart pointer itself.

Ok, so see how it is possible to pass the address of a variable to a function that requires a pointer like so:
void func(int* x)
{
//some code
}
int y = 9;
func(&y);
Is it possible to do something similar to what is above if the function was like the following:
void func(std::unique_ptr x)
{
//some code
}
How could I pass it y if I didn't want to make y a unique_ptr for a reason or another?
If a function takes a std::unique_ptr<int> argument then it expects to take ownership of the variable. Of course, you should not pass it the address of an automatic variable. You would have to create a copy of the value, like so:
func(std::make_unique<int>(y));
You can't. It doesn't have anything to do with a unique_ptr. A function takes a list of parameters of certain types. That's the only parameters that the function will accept. That's how C++ works.
Your options are:
Convert the parameter to the type that the function wants. Not an option if it's a unique_ptr.
Write an overloaded version of the function that takes a different parameter.
Write the function as a template function.
If std::unique_ptr has a proper constructor, then yes. But you would have to create a template function in that case or, at least, specify the type of your object (in your case - int)
Template function:
template<typename VarType>
void func(std::unique_ptr<VarType> x)
{
//some code
}
Specific case:
void func(std::unique_ptr<int> x)
{
//some code
}

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.

C++ Pointer can call Member Function without Object

Amazingly people may call it feature but I use to say it another bug of C++ that we can call member function through pointer without assigning any object. See following example:
class A{
public:
virtual void f1(){cout<<"f1\n";}
void f2(){cout<<"f2\n";};
};
int main(){
A *p=0;
p->f2();
return 0;
}
Output:
f2
We have checked this in different compilers & platforms but result is same, however if we call virtual function through pointer without object then there occur run-time error. Here reason is obvious for virtual function when object is checked it is not found so there comes error.
This is not a bug. You triggered an Undefined Behavior. You may get anything including the result you expected.
Dereferencing a NULL pointer is undefined behavior.
BTW, there is no thing such as "bug of C++". The bugs may occur in C++ Compilers not in the language it self.
As pointed out, this is undefined behaviour, so anything goes.
To answer the question in terms of the implementation, why do you see this behaviour?
The non-virtual call is implemented as just an ordinary function call, with the this pointer (value null) passed in as paremeter. The parameter is not dereferenced (as no member variables are used), so the call succeeds.
The virtual call requires a lookup in the vtable to get the adress of the actual function to call. The vtable address is stored in a pointer in the data of the object itself. Thus to read it, a de-reference of the this pointer is required - segmentation fault.
When you create a class by
class A{
public:
virtual void f1(){cout<<"f1\n";}
void f2(){cout<<"f2\n";};
};
The Compiler puts the code of member functions in the text area.
When you do p->MemberFunction() then the compiler just deferences p and tries to find the function MemberFunction using the type information of p which is Class A.
Now since the function's code exists in the text area so it is called. If the function had references to some class variables then while accessing them, you might have gotten a Segmentation Fault as there is no object, but since that is not the case, hence the function executes properly.
NOTE: It all depends on how a compiler implements member function access. Some compiler may choose to see if the pointer of object is null before accessing the member function, but then the pointer may have some garbage value instead of 0 which a compiler cannot check, so generally compilers ignore this check.
You can achieve a lot with undefined behavior. You can even call a function which only takes 1 argument and receive the second one like this:
#include <iostream>
void Func(int x)
{
uintptr_t ptr = reinterpret_cast<uintptr_t>(&x) + sizeof(x);
uintptr_t* sPtr = (uintptr_t*)ptr;
const char* secondArgument = (const char*)*sPtr;
std::cout << secondArgument << std::endl;
}
int main()
{
typedef void(*PROCADDR)(int, const char*);
PROCADDR ext_addr = reinterpret_cast<PROCADDR>(&Func);
//call the function
ext_addr(10, "arg");
return 0;
}
Compile and run under windows and you will get "arg" as result for the second argument. This is not a fault within C++, it is just plain stupid on my part :)
This will work on most compilers. When you make a call to a method (non virtual), the compiler translates:
obj.foo();
to something:
foo(&obj);
Where &obj becomes the this pointer for foo method. When you use a pointer:
Obj *pObj = NULL;
pObj->foo();
For the compiler it is nothing but:
foo(pObj);
i.e.:
foo(NULL);
Calling any function with null pointer is not a crime, the null pointer (i.e. pointer having null value) will be pushed to call stack. It is up to the target function to check if null was passed to it. It is like calling:
strlen(NULL);
Which will compile, and also run, if it is handled:
size_t strlen(const char* ptr) {
if (ptr==NULL) return 0;
... // rest of code if `ptr` is not null
}
Thus, this is very much valid:
((A*)NULL)->f2();
As long as f2 is non-virtual, and if f2 doesn't read/write anything out of this, including any virtual function calls. Static data and function access will still be okay.
However, if method is virtual, the function call is not as simple as it appears. Compiler puts some additional code to perform late binding of given function. The late binding is totally based on what is being pointed by this pointer. It is compiler dependent, but a call like:
obj->virtual_fun();
Will involve looking up the current type of obj by virtual function table lookup. therefore, obj must not be null.