Does OpenSSL have a concept of a callback/user pointer that you can set and use to "pass" member function pointers via forwarding through a static function pointer?
Related
If a pointer to a structure, inside one function, is dereferenced and passed as an argument to another function how does one access the structure's members inside that function?
For instance, a pointer to a structure is passed to a function like this:
main_logic_tick(&settings);
Inside the main_logic_tick function, the pointer is dereferenced and passed as an argument to another function (i.e. tick()):
void main_logic_tick(Settings* settings)
{
//...
state_machine.tick(*settings);
}
How do I access members of the stucture Settings via the settings-variable inside the tick()-function above? Is it a call by value or a call by reference? And finally, how should the function prototype for the tick()-function look like?
How do I access members of the stucture Settings via the settings-variable inside the tick()-function above? Is it a call by value or a call by reference? And finally, how should the function prototype for the tick()-function look like?
tick() can accept the Settings object by value or by reference. It sounds like you want it to accept its argument by reference -- that you want to be able modify the object and have the modifications be visible two functions upstream. For that, you would use:
void tick(Settings& settings);
Inside tick you would use the usual syntax for accessing members of a reference -- using the dot (.) operator.
settings.member = new_value;
While calling pointer to member function, we need to explicitly specify this:
(this->*ptr)();
If I understand correctly, we need to do that, since automatic parameter (this) passing doesn't work in this cases (maybe because we call member function using pointer to it). So I wonder, why can't we just call it and explicitly pass this as parameter?
ptr(this); / compile error
I always wondered why there is a stylistic difference between calling a pointer to function vs calling a pointer to a member function in terms of using the de-referencing operator *, i.e.
void(*fptr)()=&f; // pointer to function f()
fptr(); // call f() via pointer to function
Foo foo; // instance of Foo
void (Foo::*fptr)()=&Foo::f; // pointer to member function f()
(foo.*fptr)(); // call foo.f() via pointer to member function
In the first part, you don't use the * operator to call f() via the function pointer, but then one must use it in calling the member function via the pointer, (foo.*fptr)(). Why this difference? Why not just use (foo.fptr)() for consistency? Is there any profound reason or just this is the way C++ was designed?
I'll be quoting stuff from C++ Common Knowledge. The related chapter is titled Pointers to member functions are not pointers. There the author explains why pointers to member functions cannot be implemented as pointer to functions. I'll be using this (the fact that they're different things) as a justification for the different syntax :
When you take the address of a non-static member function, you don't get an address; you get a pointer to member function.
(...)
As with a pointer to data member, we need an object or pointer to an object in order to dereference a pointer to member function. (...) In the case of a pointer to member function, we need the object's address to use as (or to calculate) the value of the this pointer for the function call and possibly for other reasons as well.
Note that there is no such thing as a "virtual" pointer to member function. Virtualness is a property of the member function itself, not the pointer that refers to it.
This is one reason why a pointer to member function cannot be implemented, in general, as a simple pointer to function. The implementation of the pointer to member function must store within itself information as to whether the member function to which it refers is virtual or nonvirtual, information about where to find the appropriate virtual function table pointer, an offset to be added to or subtracted from the function's this pointer and possibly other information. A pointer to member function is commonly implemented as a small structure that contains this information, although many other implementations are also in use.
Dereferencing and calling a pointer to member function usually involves examining the stored information and conditionally executing the appropriate virtual or nonvirtual function calling sequence.
IMHO considering these differences one can justify the syntax difference, although historic design choices could have played their role.
If we simply use foo.fptr, it is the same as how we call a member function, making the compiler complex. Actually, fptr is not a member function of foo. Thus *fptr shows the difference. Maybe the compile can make that happen ,and I think that's how C++ was designed now.
I read over the boost::function function wrappers, and the examples cited in the tutorial section (http://www.boost.org/doc/libs/1_55_0/doc/html/function/tutorial.html). I am trying to understand the use cases of function wrappers, as opposed to just using function pointers. I am not necessarily looking for code samples, but more of cases where functions wrappers are way more appropriate to use than function pointers.
Thank you,
Ahmed.
A function wrapper wraps any callable entity, this includes function pointers as well as function objects and lambda functions.
A function object can be any class that overloads the operator().
Function objects are also the result of calls such as boost::bind or std::bind.
The use of a function wrapper then would be to allow any type of callable object to be used instead of just a function pointer.
Function objects are mostly used to bind values to the object such as maintaining an internal counter to determine how many times the function object was called (tricky to do with just function pointers requiring static variables in the scope of the function pointer), or binding a class instance to a member function for ease of calling later.
By having your class constructor or function take as a parameter a boost::function (or std::function) function wrapper instead of a function pointer, you allow users of your class or function to be able to decide whether they would prefer to pass you a function pointer or a function object or a lambda, and you don't have to care what choice they make.
Code like this:
int code = pthread_create(&d->thread_id, &attr, QThreadPrivate::start, this);
which QThreadPrivate::start is a static function.
So,what use is the fourth parameter this? And what is the difference if this is replaced by NULL?
This is a common idiom. You want to start a thread, but you want that thread to operate on a specific object. So you need to pass the thread a pointer to the object you want it to operate on. If you're within a member function for that object, the this pointer points to the object you're operating on. You can't pass a pointer to a member function directly (because the type would be different), so you use a static member function whose sole purpose is to cast the this pointer back to the correct type and run a non-static member function.
If you changed this to NULL, the thread would have no idea what object it was supposed to operate on. Likely, QThreadPrivate::start would fault or fail, since it would be unable to invoke a non-static member function on the instance without a pointer to that instance.
Say you have a class that has a normal member function that takes no parameters and returns no parameters. You have some code that has no idea about your class or any of its structures. You want to give that code enough information to call that member function on a particular class instance. What do you pass it? You can't pass it a pointer to the member function because with no idea about your class, it can't call a normal class member function. Answer: You pass it a pointer to a static member function whose implementation calls the normal member function, and you pass it a pointer to the instance whose method you want it to invoke.
The fourth parameter of pthread_create is passed untouched to the thread function and allows that function to change behaviour based on that argument.
OpenGroup documentation for pthread_create, detailing this, can be found here.
In this case, it's simply passing the pointer to the current object, presumably so that the start function can use that to access member variables for the specific object.
If you pass NULL instead, the created thread will get NULL and won't be able to access object specific data (without crashing and burning badly with a null pointer dereference).
You may think that, because QThreadPrivate::start is a static function, it wouldn't be able to access non-static members any way (since it generally doesn't have an object to work on).
But that only applies to implicit access - there's nothing stopping you from accessing object data through an explicit this pointer, providing you follow the access rules (e.g., no access to private data).
The fourth parameter is passed to the thread when it starts. QThreadPrivate::start can use it (after an appropriate cast) to call an object specific member function.