Stuck with function pointers in C and C++
-
I'm trying to copy some C code to a C++ class and I've got stuck with a function pointer issue. I've been trying to mess around with calling conventions but I don't want to make my C++ function static and don't want to change the old C code. Thanks for looking.
class theClass
{
public:
int theFunction(int theParam1);
int anotherFunction(void);
};typedef int (*funcPtr) (int Param1);
int theClass::theFunction(int theParam1)
{
return 0;
}int function(int theParam1)
{
return 0;
}bool globFunction (funcPtr aFunction, bool someOtherArg)
{
int anArg = 0;
int ret = aFunction(anArg);
return true;
}int theClass::anotherFunction(void)
{
globFunction (function, false);globFunction (&theClass::theFunction, true); // error C2440: 'type cast' : cannot convert from 'int (\_\_thiscall theClass::\* )(int)' to 'funcPtr' return 0;
}
-
I'm trying to copy some C code to a C++ class and I've got stuck with a function pointer issue. I've been trying to mess around with calling conventions but I don't want to make my C++ function static and don't want to change the old C code. Thanks for looking.
class theClass
{
public:
int theFunction(int theParam1);
int anotherFunction(void);
};typedef int (*funcPtr) (int Param1);
int theClass::theFunction(int theParam1)
{
return 0;
}int function(int theParam1)
{
return 0;
}bool globFunction (funcPtr aFunction, bool someOtherArg)
{
int anArg = 0;
int ret = aFunction(anArg);
return true;
}int theClass::anotherFunction(void)
{
globFunction (function, false);globFunction (&theClass::theFunction, true); // error C2440: 'type cast' : cannot convert from 'int (\_\_thiscall theClass::\* )(int)' to 'funcPtr' return 0;
}
-
I'm trying to copy some C code to a C++ class and I've got stuck with a function pointer issue. I've been trying to mess around with calling conventions but I don't want to make my C++ function static and don't want to change the old C code. Thanks for looking.
class theClass
{
public:
int theFunction(int theParam1);
int anotherFunction(void);
};typedef int (*funcPtr) (int Param1);
int theClass::theFunction(int theParam1)
{
return 0;
}int function(int theParam1)
{
return 0;
}bool globFunction (funcPtr aFunction, bool someOtherArg)
{
int anArg = 0;
int ret = aFunction(anArg);
return true;
}int theClass::anotherFunction(void)
{
globFunction (function, false);globFunction (&theClass::theFunction, true); // error C2440: 'type cast' : cannot convert from 'int (\_\_thiscall theClass::\* )(int)' to 'funcPtr' return 0;
}
If I remember correctly, you can't declare a pointer to a non-static member function in native C++. If you need to keep the original functions as they are, I would add a static helper function which gets the class object pointer as additional parameter and calls the member function. Something like that:
/*static*/ int theClass::theFunctionCaller(theClass * obj, int theParam1)
{
if (obj != NULL)
obj->theFunction(theParam1);
}bool globFunction (theClass * obj, funcPtr aFunction)
{
int anArg = 0;
int ret = aFunction(obj, anArg);
return true;
}int theClass::anotherFunction(void)
{
globFunction (this, &theClass::theFunctionCaller, true);
}If you need the globFunction() for different classes, you could pass the obj as void * and cast it back in the helper function, because you know which class it is for at that point.
-
If I remember correctly, you can't declare a pointer to a non-static member function in native C++. If you need to keep the original functions as they are, I would add a static helper function which gets the class object pointer as additional parameter and calls the member function. Something like that:
/*static*/ int theClass::theFunctionCaller(theClass * obj, int theParam1)
{
if (obj != NULL)
obj->theFunction(theParam1);
}bool globFunction (theClass * obj, funcPtr aFunction)
{
int anArg = 0;
int ret = aFunction(obj, anArg);
return true;
}int theClass::anotherFunction(void)
{
globFunction (this, &theClass::theFunctionCaller, true);
}If you need the globFunction() for different classes, you could pass the obj as void * and cast it back in the helper function, because you know which class it is for at that point.
Yes, good answer. Thanks for that. :)
-
If I remember correctly, you can't declare a pointer to a non-static member function in native C++. If you need to keep the original functions as they are, I would add a static helper function which gets the class object pointer as additional parameter and calls the member function. Something like that:
/*static*/ int theClass::theFunctionCaller(theClass * obj, int theParam1)
{
if (obj != NULL)
obj->theFunction(theParam1);
}bool globFunction (theClass * obj, funcPtr aFunction)
{
int anArg = 0;
int ret = aFunction(obj, anArg);
return true;
}int theClass::anotherFunction(void)
{
globFunction (this, &theClass::theFunctionCaller, true);
}If you need the globFunction() for different classes, you could pass the obj as void * and cast it back in the helper function, because you know which class it is for at that point.
Cheers.. I'm having a play with this but you've modified globFunction, which in my case I'm really trying to avoid. Also it wont build as it stands (you can't call non static functions from a static function).
error C2352: 'theClass::theFunction' : illegal call of non-static member function
-
If I remember correctly, you can't declare a pointer to a non-static member function in native C++. If you need to keep the original functions as they are, I would add a static helper function which gets the class object pointer as additional parameter and calls the member function. Something like that:
/*static*/ int theClass::theFunctionCaller(theClass * obj, int theParam1)
{
if (obj != NULL)
obj->theFunction(theParam1);
}bool globFunction (theClass * obj, funcPtr aFunction)
{
int anArg = 0;
int ret = aFunction(obj, anArg);
return true;
}int theClass::anotherFunction(void)
{
globFunction (this, &theClass::theFunctionCaller, true);
}If you need the globFunction() for different classes, you could pass the obj as void * and cast it back in the helper function, because you know which class it is for at that point.
Freak30 wrote:
If I remember correctly, you can't declare a pointer to a non-static member function in native C++
Actually you can, e.g.
#include<iostream>
using namespace std;class A
{
int i;
public:
A(int i):i(i){}
void show() { cout << i << endl;}
};void (A::*pmfn)();
int main()
{
A a(7);pmfn = &A::show;
(a.*pmfn)();
}However (and of course) this kind of pointer is not compatible with
C
-like function pointers.Veni, vidi, vici.
-
I'm trying to copy some C code to a C++ class and I've got stuck with a function pointer issue. I've been trying to mess around with calling conventions but I don't want to make my C++ function static and don't want to change the old C code. Thanks for looking.
class theClass
{
public:
int theFunction(int theParam1);
int anotherFunction(void);
};typedef int (*funcPtr) (int Param1);
int theClass::theFunction(int theParam1)
{
return 0;
}int function(int theParam1)
{
return 0;
}bool globFunction (funcPtr aFunction, bool someOtherArg)
{
int anArg = 0;
int ret = aFunction(anArg);
return true;
}int theClass::anotherFunction(void)
{
globFunction (function, false);globFunction (&theClass::theFunction, true); // error C2440: 'type cast' : cannot convert from 'int (\_\_thiscall theClass::\* )(int)' to 'funcPtr' return 0;
}
What you're trying to do makes no sense. You're trying to call a non-static member function without an instance of the class or any mechanism to identify one.
Steve
-
Freak30 wrote:
If I remember correctly, you can't declare a pointer to a non-static member function in native C++
Actually you can, e.g.
#include<iostream>
using namespace std;class A
{
int i;
public:
A(int i):i(i){}
void show() { cout << i << endl;}
};void (A::*pmfn)();
int main()
{
A a(7);pmfn = &A::show;
(a.*pmfn)();
}However (and of course) this kind of pointer is not compatible with
C
-like function pointers.Veni, vidi, vici.
-
Cheers.. I'm having a play with this but you've modified globFunction, which in my case I'm really trying to avoid. Also it wont build as it stands (you can't call non static functions from a static function).
error C2352: 'theClass::theFunction' : illegal call of non-static member function
If modifying your global function is out of the question, then you can only pass it either a global function or a
static
class function. There is no other way. As CPallini remarked, the type of a pointer to a nonstatic member function is incompatible with your function pointer type definition. What's more: a pointer to a nonstatic member function requires more memory to store than a simple function pointer, so casting is out of the question, too! The question is: what is your goal? You're converting code, so why can't you change that global function? If you really can't, the only solution I can think of would be a wrapper function that calls your member function indirectly:namespace wrapper {
class theClass* instance; // global variable required!
int theClassWrapper(int arg) {
int ret = 0;
if (instance != nullptr)
ret = instance->theFunction(arg);
return ret;
}
};
int theClass::anotherFunction() {
wrapper::instance = this;
return globFunction(&wrapper::theClassWrapper, true);
}I've put the required additional global variable and global function inside a namespace to minimize global namespace polution and risk of conflicts, but you cannot avoid these additional globals if you cannot modify your existing global function.
-
If modifying your global function is out of the question, then you can only pass it either a global function or a
static
class function. There is no other way. As CPallini remarked, the type of a pointer to a nonstatic member function is incompatible with your function pointer type definition. What's more: a pointer to a nonstatic member function requires more memory to store than a simple function pointer, so casting is out of the question, too! The question is: what is your goal? You're converting code, so why can't you change that global function? If you really can't, the only solution I can think of would be a wrapper function that calls your member function indirectly:namespace wrapper {
class theClass* instance; // global variable required!
int theClassWrapper(int arg) {
int ret = 0;
if (instance != nullptr)
ret = instance->theFunction(arg);
return ret;
}
};
int theClass::anotherFunction() {
wrapper::instance = this;
return globFunction(&wrapper::theClassWrapper, true);
}I've put the required additional global variable and global function inside a namespace to minimize global namespace polution and risk of conflicts, but you cannot avoid these additional globals if you cannot modify your existing global function.
Thanks for the reply - my original question was based on the premise that my casting or function declaration was wrong in some way - actually it looks like getting a pointer to a non-static class function and then casting it to match the original 'C' functions isn't straightforward. So solution 1 - make the function and all the class variables static. solution 2 - examine the original 'C' function that takes the function pointer and re-implement it. Thanks for looking. :)
-
Thanks for the reply - my original question was based on the premise that my casting or function declaration was wrong in some way - actually it looks like getting a pointer to a non-static class function and then casting it to match the original 'C' functions isn't straightforward. So solution 1 - make the function and all the class variables static. solution 2 - examine the original 'C' function that takes the function pointer and re-implement it. Thanks for looking. :)
It 'isn't straightforward' in the same sense that casting a
double
tochar
would be. The types are not the compatible, not even the same size.