Passing a function pointer by reference - c++

Hi I am trying to learn some function pointers in C/C++ and I was trying to write the following C++ code with gcc on Ubuntu.
This code should execute the multiply or or the add function depending on the
preprocessor flag -DADD or -DMULTIPLY provided during compilation
#include <iostream>
#include <iomanip>
//Adds two numbers
int add(int a, int b)
{
return a+b;
}
//Multiplies two numbers
int multiply(int a, int b)
{
return a*b;
}
//Function to set the correct function to be executed.
//All functions here should have the same signature.
void functionsetter( void (*ptr2fun)(int,int) )
{
#ifdef ADD
ptr2fun = add;
#endif
#ifdef MULTIPLY
ptr2fun = multiply
#endif
}
int main(int argc, char *argv[])
{
int a = 5;
int b = 6;
void (*foo)(int,int);
functionsetter(foo);
return 0;
}
I cannot figure out how to pass the function pointer foo to the function-setter function by reference. Can someone help me out on this.I am sure the declaration of
functionsetter is wrong in the code, Please let me know how to fix it.
I am trying to compile this with g++ -O2 -g -Wall -DADD main.cpp -o main
Note: I want to use such preprocessor flags and function pointers in some other-code elsewhere.
Please let me know if such a thing is a good idea / practice.

Without using a typedef, the syntax for a reference to a function pointer is:
void functionsetter(void (*&ptr2fun)(int, int)) { ... }
But it is generally simpler to create a typedef for the pointer type:
typedef void (*FunctionPointer)(int, int);
void functionsetter(FunctionPointer& ptr2fun) { ... }
Or for the function type:
typedef void Function(int, int);
void functionsetter(Function*& ptr2fun) { ... }

Use a typedef:
typedef void (*MyFunctionPointer)(int,int);
void functionsetter(MyFunctionPointer& fp);
I want to use such preprocessor flags and function pointers in some other-code elsewhere. Please let me know if such a thing is a good idea / practice.
No, not really. It isn't clear from your example what you are trying to accomplish, but your implementation is rather unusual. Consider using virtual member functions or std::function to switch function implementations at runtime, or (possibly) templates to switch them at compile-time. There's nothing wrong with using conditional compilation for static selection like this, but mixing that with function pointers is a bit odd.
Without a good understanding of the problem you are trying to solve, it's difficult to give good advice as to how best to solve it.

You'd change your signature to:
void functionsetter( void (*&ptr2fun)(int,int) )
Note that the ptr2fun function pointer has the wrong signature, your add and multiply functions return an int, and so should ptr2fun
This becomes a lot easier if you use a typedef:
typedef int (*ptr2fun)(int,int);
void functionsetter(ptr2fun& func) { ...
Though, personally I'd just return the function pointer.
ptr2fun functionsetter()
{
#ifdef ADD
return add;
#endif
#ifdef MULTIPLY
return multiply
#endif
}

First, you're not passing a function pointer reference to the method, you're just passing a function pointer. You need to change the method signature to
void functionsetter( void (*&ptr2fun)(int,int) )
Also, your method signature is void(*)(int,int) in some places and int(*)(int,int) in some, they should probably be the latter everywhere since your add and multiply methods return int.
That said, since you're using C++, manipulating pointers in this manner isn't something I'd recommend, C++ has inheritance/virtual methods that can usually replace most function pointer use and makes the code much more readable and extensible.

Related

mingw - cdecl required to run functions correctly

The code below is running correctly with any online gcc compiler I found (gcc 9.2.0), it also run correctly with CYGWIN gcc compiler, but unfortunately it doesn't work well with MINGW gcc compiler - looks like it passes invalid parameter as "this" to "methodA" and "methodB" methods, when they are called, instead of expected results (56,58) i get some random high numbers.
#include <iostream>
using namespace std;
class CallbackBase
{
public:
using METHOD_TYPE = int (CallbackBase::*)(...);
};
class CallbackProvider : public CallbackBase
{
public:
int methodA(int a,int b,int c)
{
return a+b+c+d;
}
int methodB(double a,double b,double c)
{
return a+b+c+d;
}
private:
int d=8;
};
class CallbackRunner
{
public:
CallbackBase::METHOD_TYPE m_method;
CallbackBase* m_this;
void install (CallbackBase* _this, CallbackBase::METHOD_TYPE _method)
{
m_method =_method;
m_this =_this;
}
int Run1()
{
return (m_this->*m_method)(15L,16L,17L);
}
int Run2()
{
return (m_this->*m_method)(15.6,16.7,17.8);
}
};
int main()
{
CallbackProvider cp;
CallbackRunner cr;
cr.install(&cp,(CallbackBase::METHOD_TYPE)&CallbackProvider::methodA);
cout << "result " << cr.Run1() << endl;
cr.install(&cp,(CallbackBase::METHOD_TYPE)&CallbackProvider::methodB);
cout << "result " << cr.Run2() << endl;
return 0;
}
The problem is solved if I add __cdecl attribute to this methods:
int __cdecl methodA(int a,int b,int c)
int __cdecl methodB(double a,double b,double c)
I doesn't use -mrtd compilation flag.
According to this, __cdecl should be a default calling convention for gcc compilers but looks like it doesn't the case for MINGW.
Is that possible to set __cdecl as a default calling convention for my project?
or as alternative, is there a way to set "default" attribute to all the methods?
I am using Windows 10 with 64 bit architecture.
You're not allowed to use a pointer to function with a C-style variadic parameter to call functions with regular parameters. There's a reason your cr.install calls don't work without a pointer cast.
The simplest solution is to cast the callback pointer to the proper type before calling it, based on the arguments you want to call it with. You can write a template that will do the cast for you.
However, this is highly unsafe, since it's easy to cast to an incorrect type. (Your code would be equally unsafe, if it wasn't undefined to begin with.)
A safer approach is to store the function pointer in a std::any. Then, attempting a callback call with invalid parameters will cause a runtime error (that is, std::any_cast will detect parameter type mistmatch).
Your code has a bug - it has undefined behavior. The cast from int (Class::*)(int, int, int) to int (CallbackBase::*)(...) triggers it. Those two types are not the same, and you can not cast between them willy-nilly.
This is an extract of your code where you are attempting this illegal cast:
cr.install(&cp,(CallbackBase::METHOD_TYPE)&CallbackProvider::methodA);
You can easily see the diagnostic message yourself if you remove the cast:
error: cannot convert 'int (CallbackProvider::*)(int, int, int)' to 'CallbackBase::METHOD_TYPE' {aka 'int (CallbackBase::*)(...)'}
The fact that it works on some compilers and not on the others is of no significance, it is just a manifestation of undefined behavior.
You could cast back to the original function type before calling it, but than the whole thing would become even more ugly.
Another option might be to make your concrete functions variadic as well, and access parameters via VA_ARGS. This would throw the whole C++ type safety off the window, and I do not like this approach either.
Just for the trivia, it looks like mingw's gcc uses a legacy calling convention (cdecl is indeed quite legacy) for variadic functions, while other compilers would use modern AMD ABI.

Can I use std::bind to convert a pointer to member function into a pointer to function?

I want to pass a member function as a call-back. The call back is a basic function pointer.
So I have something like:
h file:
void (*pRequestFunc) (int someint) = 0;
void RegisterRequestCallBack(void (*requestFunc) (int someint))
{
pRequestFunc = requestFunc;
}
class A
{
void callBack(int someint);
}
Cpp File:
RegisterRequestCallBack(&A::callBack); // This does not work.
Note I have tried to extract this example from my larger example and cut out all the other stuff - so it might not be perfect.
The problem, as far as I understand, is that member function pointers really (under the hood) have an extra parameter (and instance - i.e. this) and are not compatible with normal function pointers.
the RegisterRequestCallBack() is in reality not my code - and so I can't change that.
So I read that boost::bind can do what I need - and I am hoping c++11 std::bind can do the same - but I could not figure out how to use it to effectively get a standard function pointer from a member function pointer...
I was going for something like:
std::bind(&A::callBack) ... that is about as far as I got, my understanding of the examples online is poor :(
NathanOliver's comment is correct, and your suspicion is mostly correct. Exactly how pointers to member functions work is not specified, but including this as a hidden argument mostly works. You just need a bit of extra work for inheritance and pointers to virtual functions (yes, you can take their address too).
Now, often callbacks include a void* parameter under your control, which you can use to pass a A*. In those cases, you can write a wrapper (static) function that casts the void* back to A* and does the actual call to &A::callback.
That's not the case here. Registration takes a single function, without data. To get this to work in real-life situations, you have to resort to drastic solutions - not portable C++. One such method is to dynamically generate assembly (!). You create - at runtime - the compiled equivalent of
void __trampoline_0x018810000 (int i)
{
A* __this = reinterpret_cast<A*>(0x018810000);
__this->callback(i);
}
As you can see, you have to generate one trampoline for every A* value, and managing lifetimes of these is a major pain.
To be able to bind to a member function you need to do:
std::function<void(int)> function = std::bind(&A::foo, this, std::placeholders::_1);
Or in your case:
RegisterRequestCallBack(std::bind(&A::callback, this, std::placeholders::_1));
But in my opinion the clearest way to achieve this is to use lambda functions. Here you have an example to for doing something similar that could inspire you:
#include <array>
#include <map>
#include <vector>
#include <functional>
#include <iostream>
class TaskManager {
public:
using task_t = std::function<void()>;
void run();
void addTask(task_t task);
private:
std::vector<task_t> _tasks;
};
void TaskManager::run() {
for (auto& task : _tasks) {
task();
}
}
void TaskManager::addTask(task_t task) {
_tasks.push_back(task);
}
class Example {
public:
Example(){
taskManager.addTask([this]() {
task1();
});
taskManager.addTask([this,a=int(4)](){
task2(a);
});
}
TaskManager taskManager;
private:
void task1(){ std::cout << "task1!\n"; }
void task2(int a){ std::cout << "task2 says: " << a << "\n"; }
};
int main() {
Example example;
example.taskManager.run();
}
which outputs:
task1!
task2 says: 4

What is the syntax for calling a member function pointer that is a member of a structure array in C++

This question is similar to what I'm trying to do Calling C++ member function pointer from a struct .
However my structure contains a member function pointer that is defined in a different class then the one the structure is defined and used in. Here is some example code of how my classes, structures and function pointers are laid out.
// Alpha.h:
class Alpha{
public:
void function1(char name[], int number);
void function2(char name[], int number);
void function3(char name[], int number);
typedef void (Alpha::*My_func_ptr)(char name[], int number);
static My_func_ptr functionTable[];
};
// Alpha.cpp:
#include "Alpha.h"
Alpha::My_func_ptr Alpha::functionTable[] = {
&Alpha::function1,
&Alpha::function2,
&Alpha::function3
};
void Alpha::function1(char name[], int number)
{
//some stuff
}
void Alpha::function2(char name[], int number)
{
//some stuff
}
void Alpha::function3(char name[], int number)
{
//some stuff
}
// Beta.h:
#include "Alpha.h"
typdef struct{
char bName[10];
Alpha::My_func_ptr fptr;
}ptr_structure;
class Beta{
public:
void betafunction();
Alpha alphaobject;
ptr_structure str_array[3];
};
// Beta.cpp:
#include "Beta.h"
void betafunction()
{
str_array[0].fptr = alphaobject.functionTable[0];
str_array[1].fptr = alphaobject.functionTable[1];
str_array[2].fptr = alphaobject.functionTable[2];
(str_array[0].fptr)("name", 1); //gives error expression must have
//(pointer-to-) function type
(this->*str_array[0].fptr)("name", 1);
//error pointer-to-member selection class types are incompatible "Beta" and "Alpha"
//sample function pointer call using function table from other class,
//this syntax compiles and runs without error.
(alphaobject.*Alpha::functionTable[0]("name", 1);
}
As you can see I can call the function pointer from an array, but can't seem to figure out how to call a function pointer from inside an array of structures.
When calling a through member function pointer, you need to have an instance of the object associated with that pointer:
(alphaobject.*(str_array[0].fptr))("name", 1)
^^^^^^^^^^^
I would think:
(object.*functionTable[0])(args, ...);
(objptr->*functionTable[0])(args, ....);
IIRC, the combination of object and the .* operator is like a big unary operator. So that has lower precedence to the [0] postfix. However, it also has lower prededence than the function call postfix operator (args, ...)
Analogy:
(*foo)(); /* classic C */
Of course the * operator is not required when calling a regular function. But if you do write it, you need the parens, because *foo() means something else.
You can go to one of two solutions, depending on how readable you want the code. The unreadable version (which might even be wrong, and I won't even try to compile):
void Beta::betafunction() {
Alpha a;
(a.*(strArray[0].fptr))("name",1);
}
But I would actually try to make things a bit simpler:
void Beta::betafunction() {
Alpha a;
Alpha::My_func_ptr mptr = strArray[0].fptr;
(a.*mptr)("name",1);
}
I believe the second to be much more readable, and the compiler can optimize away mptr pretty easily, so there is no point in trying to play guru with the syntax.

a "general function signature" pointer that points to an arbitrary function

I'll try to explain better what I want to do.
I read a file with function signatures, and I want to create a pointer to each function.
For example, a file that looks like this:
something.dll;int f(char* x, int y, SOMESTRUCT z)
something.dll;void g(void)
something.dll;SOMESTRUCT l(longlong w)
now, during runtime I want be able to create pointers to these functions (by loading something.dll and using GetProcAddress to these functions).
Now, GetProcAddress returns FARPROC which points to an arbitrary functions, but how can I use FARPROC to call these functions during runtime?
From what I know, I need to cast FARPROC to the correct signature, but I can't do it during runtime (or at least I don't know how).
Does anyone have any idea how to design do that?
Thanks! :-)
Function types are compile-time in C++, so it won't work, unless you can define all the types you're going to use in advance.
Its a matter of pushing the arguments to the stack (and local vars are like that) and calling the function as void (__cdecl *)(void).
With some other kinds of functions (like fastcall, or thiscall) it can be more problematic.
Update: I actually made an example, and it works on codepad:
(Also works with stdcall functions, because of stack restore after aligned stack alloc)
http://codepad.org/0cf0YFRH
#include <stdio.h>
#ifdef __GNUC__
#define NOINLINE __attribute__((noinline))
#define ALIGN(n) __attribute__((aligned(n)))
#else
#define NOINLINE __declspec(noinline)
#define ALIGN(n) __declspec(align(n))
#endif
//#define __cdecl
// Have to be declared __cdecl when its available,
// because some args may be passed in registers otherwise (optimization!)
void __cdecl test( int a, void* b ) {
printf( "a=%08X b=%08X\n", a, unsigned(b) );
}
// actual pointer type to use for function calls
typedef int (__cdecl *pfunc)( void );
// wrapper type to get around codepad's "ISO C++" ideas and gcc being too smart
union funcwrap {
volatile void* y;
volatile pfunc f;
void (__cdecl *z)(int, void*);
};
// gcc optimization workaround - can't allow it to know the value at compile time
volatile void* tmp = (void*)printf("\n");
volatile funcwrap x;
int r;
// noinline function to force the compiler to allocate stuff
// on stack just before the function call
NOINLINE
void call(void) {
// force the runtime stack pointer calculation
// (compiler can't align a function stack in compile time)
// otherwise, again, it gets optimized too hard
// the number of arguments; can be probably done with alloca()
ALIGN(32) volatile int a[2];
a[0] = 1; a[1] = 2; // set the argument values
tmp = a; // tell compiler to not optimize away the array
r = x.f(); // call the function; returned value is passed in a register
// this function can't use any other local vars, because
// compiler might mess up the order
}
int main( void ) {
// again, weird stuff to confuse compiler, so that it won't discard stuff
x.z = test; tmp=x.y; x.y=tmp;
// call the function via "test" pointer
call();
// print the return value (although it didn't have one)
printf( "r=%i\n", r );
}
Once you have a FARPROC, you can cast the FARPROC into a pointer to the appropriate function type. For example, you could say
int (*fPtr)(char*, int, SOMESTRUCT) = (int (*)(char*, int, SOMESTRUCT))GetProcAddress("f");
Or, if you want to use typedefs to make this easier:
typedef int (*FType)(char *, int, SOMESTRUCT);
FType fPtr = (FType)GetProcAddress("f");
Now that you have the function pointer stored in a function pointer of the appropriate type, you can call f by writing
fPtr("My string!", 137, someStructInstance);
Hope this helps!
The compiler needs to know the exact function signature in order to create the proper setup and teardown for the call. There's no easy way to fake it - every signature you read from the file will need a corresponding compile-time signature to match against.
You might be able to do what you want with intimate knowledge of your compiler and some assembler, but I'd recommend against it.

Function definition and function type

I have the following code which works as expected:
#include <iostream>
using namespace std;
typedef int (TMyFunc)(int);
TMyFunc* p;
int x(int y)
{
return y*2;
}
int main()
{
p = &x;
cout << (*p)(5) << endl;
}
What I want to do is skip defining x and define p there straight. Something like
TMyFunc p; p(y){return y*2;}.
Is that possible? If so how do I do it? If not why?
EDIT:
After seeing the answers, I think I should clarify: I want the definition to be separate. i.e. function definition will be in a shared object. An application will acquire a function pointer to the function via dlsym. I do not want a function object. What I want is to know if I can define a function using its type which a header file common to both the shared object and the application will provide. I hope that came out right :).
EDIT2: For sbi :)
This resides in a header which is included in both the application and the shared object:
#define FNAME_GET_FACTORY "GetFactory"
#define FNAME_GET_FUNCTION_IDS "GetFunctionIDs"
#define FNAME_GET_PLUGIN_INFO "GetPluginInfo"
typedef FunctionFactory* (*TpfGetFactory)();
typedef size_t (*TpfGetFunctionIDs)(int**);
typedef PluginInfo* (*TpfGetPluginInfo)();
In the application, something like this happens:
TpfGetFactory pF = (TpfGetFactory)dlsym(pHandle, FNAME_GET_FACTORY);
//Use pF for anything
Now, to do this, I have to define GetFactory as follows in the shared object:
extern "C" FunctionFactory* FNAME_GET_FACTORY(){//CODE}
Forgetting the extern "C" part for now, Can I define this function using the type TpfGetFactory which is already defined? (This is not a huge issue I know - but I am curious as to whether it is possible :) ). What I want is something like this in the shared object :
TpfGetFactory f;
f(){//Implementation}
EDIT3:
My try:
#include <iostream>
using namespace std;
typedef int (TF)(int);
TF f;
f(int x)
{
return x*2;
}
int main()
{
x(3);
}
main.cpp:9: error: ISO C++ forbids declaration of ‘f’ with no type
main.cpp: In function ‘int main()’:
main.cpp:16: error: ‘x’ was not declared in this scope
It's possible in C++1x, the next C++ standard, generally expected next year (which would make it C++11, then). It allows this:
auto p = [](int y){return y*2;};
This relies on auto been given a new meaning ("automatically deduce the type of this variable from the expression that initializes it") and the new lambda functions (allowing to create functions on the fly).
Your compiler might actually already support this.
This works fine for me, with the current C++03 Standard:
typedef int (TMyFunc)(int);
TMyFunc* p;
int test()
{
struct LocalClass
{
static int functionLocal(int y)
{
return 2;
};
};
LocalClass localClass;
p = &(LocalClass::functionLocal);
}
But maybe it happens to be more complicated to write than what you wanted to simplify ;-),
however it works and you can define your functions in place, locally.
Here is some documentation about local classes
This will be possible in the next C++ standard, via lambdas. In the current standard, however, it is impossible to define one function inside another.
Not directly in C++98.
For standard C++, that is C++98, check out e.g. the Boost Lambda library. It lets you write expressions like
for_each(a.begin(), a.end(), std::cout << _1 << ' ');
C++0x adds direct support for lambda expressions.
Cheers & hth.,