|
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);
return 0;
}
|
|
|
|
|
If, in your function, you don't access members of the class then it makes more sense to make it static then implement it as ordinary member.
Veni, vidi, vici.
|
|
|
|
|
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:
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 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; 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.
|
|
|
|
|
It 'isn't straightforward' in the same sense that casting a double to char would be. The types are not the compatible, not even the same size.
|
|
|
|
|
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.
|
|
|
|
|
Ok, this is quite interesting. Of course the function pointer is now class specific, and you still need to pass a pointer to the class object. So it seems there is no way around changing the global function.
|
|
|
|
|
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
|
|
|
|