PDA

View Full Version : Pointer to non static member functions within the class



Lykurg
23rd April 2011, 17:15
Hi,

after spending a lot of time on the following problem, without any luck, I first wanted to ask if my problem is solvable:



typedef void (*fp)(int, const char*);

class A
{
public:
A()
{
fp x;
x = &A::staticMemberFunc; // works
x = &A::memberFunc; // this doesn't, but I want it to...
// (translated) error message:
// error C2440: '=': 'void (__thiscall A::* )(int,const char *)' could not be converted to 'fp'
}

private:
void memberFunc(int, const char*) {}
static void staticMemberFunc(int, const char*) {}
};


int main(int argc, char* argv[])
{
return 0;
}

If it is, some hints are highly appreciated.


Thanks,

Lykurg

P.s.: The typedef is part of a library so I can't change it.

Added after 21 minutes:

Damn! Not again ;) Found the solution right after posting...


class A
{
public:
A()
{
foo = &A::memberFunc;
fp x;
x = (fp) &foo;
}

void (A::*foo)(int, const char*);
void memberFunc(int, const char*) {}
};

Added after 18 minutes:

Ehm, :crying:, no compiler error but I get a crash when using x.

stampede
24th April 2011, 00:35
Ehm, , no compiler error but I get a crash when using x.
As long as you don't touch the parameters, it should work (but will be quite useless). First parameter of a class member method is an address of calling object ('this'), so casting it like that will cause a mess, look at this one:


#include <iostream>

typedef void (*fp)(int, int);

class A
{
public:
void method( int x, int y){
std::cout << (int)this << " " << x;
}
};

typedef void (A::*fpa)(int,int);

int main(int argc, char* argv[])
{
fpa x = &A::method;

fp f;
f = (fp)(x);
f(44,55);

return 0;
}


output is : 44 55
Arguments got "shifted", because an address of calling object is expected as first parameter ( so in fact it is void method( A * this, int, int ) ). I think it's clear enough that any use of 'this' (referencing) in such method will cause a crash, as 'this' is not valid address of calling object ( trying to call object's method without an object :) ). Last parameter passed will probably contain some garbage values.

Is this some kind of callback mechanism and you want to register object's method ?

Lykurg
24th April 2011, 06:51
Hi,

thanks for your comment, I see a little bit clearer now. But also your example don't compile (msvc) or crashes with mingw.

My original "problem" is to make a library call to astyle (because I had rearrange my plugin last time and want to release a new version). The idea was to encapsulate all astyle stuff in a single class, with simple returns the formatted source code and it should be used in parallel to speed up things for future. I can make a work around with a static error function and a mutex and grab the error string inside formatedText(), but I it would be nicer to directly use a member function (if possible).


QString ASInstance::formatedText(const QString& text)
{
m_error = false;
QByteArray baIn = text.toUtf8();
const char* textOut = AStyleMain(baIn.constData(),
m_options.constData(),
/* MAGIC goes here, must be fpError */,
&ArtisticStyle::Internal::ASInstance::memoryAlloc);
QString formattedText = QString::fromUtf8(textOut);
delete [] textOut;
return formattedText;
}

void ASInstance::errorHandler(int number, const char* message)
{
m_error = true;
m_errorNumber = number;
m_errorMessage = QString(message);
}

and from astyle.h
typedef void (STDCALL* fpError)(int, const char*); // pointer to callback error handler
extern "C" EXPORT char* STDCALL AStyleMain(const char*, const char*, fpError, fpAlloc);

stampede
24th April 2011, 07:37
But also your example don't compile (msvc) or crashes with mingw.
I don't have msvc compiler, but it worked with g++ 4.5.2, nevermind anyway.
If you want to use member method, the only thing I can think of in that case is to pass static class method pointer as callback and use member method of static instance inside, but it has obvious limitations. I think it's not possible to use member method directly, because of the "this" issue.
Maybe someone else has encountered that kind of problem and can help you more.