How to get the absolute address of an object's member function?

B

blackbiscuit

Dear all,

Suppose I have a class A which is defined as follows.

class A
{
public:
void f( int i )
{
}
};

A a;

How to get the absolute address of a.f( int )? Thank you very much!

Best,
Tony
 
I

Ian Collins

blackbiscuit said:
Dear all,

Suppose I have a class A which is defined as follows.

class A
{
public:
void f( int i )
{
}
};

A a;

How to get the absolute address of a.f( int )? Thank you very much!

That depends on you system's memory model.

What's wrong with

typedef void (A::*Fn)(int);

Fn f = A::f;
 
N

Neelesh

That depends on you system's memory model.

What's wrong with

typedef void (A::*Fn)(int);

Fn f = A::f;

this won't compile. Instead, say Fn f = &A::f

5.3.1/3
A pointer to member is only formed when an explicit & is used and its
operand is a qualifiedid
not enclosed in parentheses. [Note: that is, the expression &
(qualifiedid), where the qualifiedid
is enclosed in parentheses, does not form an expression of type
“pointer to member.” Neither does
qualifiedid, because there is no implicit conversion from a
qualifiedid for a nonstatic member function to the type “pointer to
member function” as there is from an lvalue of function type to the
type “pointer to function” (4.3). Nor is &unqualifiedid a pointer to
member, even within the scope of the unqualifiedid’s class]

However, doing "cout << f " would result in "pointer-to-member to
bool" conversion and it will print true or false (or 1 or 0)
appropriately.
 
S

SG

Suppose I have a class A which is defined as follows.

class A
{
    public:
        void f( int i )
        {
        }
};

A a;

How to get the absolute address of a.f( int )?

What exactly do you mean by absolute address of "a.f(int)"? Can you
elaborate? How would you use such an address? I'm asking because I
think what you want is this:

magic_type p = ...; // address of a.f(int)
p(23); // invoke f(int) on object a

The thing is that member functions are shared accross different
objects of the same class. You have exactly one member function 'f'
for *all* objects of class 'A'. To differentiate between objects a
member function takes an additional parameter (the 'this' pointer)
which is done automatically. What you can do is this:

void (A::*p)(int) = &A::f;
a.*p(23);

In case of data members member pointers are probably just offsets
under the hood. In case of function members member pointers are
probably the absolute address of the function. And these functions
need to know on what object they are working on (implicit 'this'
parameter) which is why you still need to say on what object you'd
like to invoke this member function.

Alternativly you can wrap such a pointer-to-member-function along with
a pointer to an object into a "function object":

auto fun2 = std::mem_fun(&A::f);
fun2(&a,23); // invokes A::f on 'a' with parameter 23

auto fun1 = std::bind1st(fun2,&a);
fun1(23); // invokes A::f on 'a' with parameter 23

Note: The use of 'auto' here for letting the compiler infer the type
is currently not supported by C++. But it's still usable if you pass
the function object to a function template like in this example:

#include <iostream>
#include <ostream>
#include <string>
#include <vector>
#include <functional>
#include <algorithm>

using namespace std;

int main() {
vector<string> sv;
sv.push_back("this");
sv.push_back("is");
sv.push_back("an");
sv.push_back("example");
vector<int> lv (sv.size());
transform( sv.begin(), sv.end(),
lv.begin(),
mem_fun_ref(&string::length) );
for (unsigned k=0, e=lv.size(); k<e; ++k) {
cout << lv[k] << endl;
}
}

std::transform (algorithm header) takes some iterators and a function
object to "transform" one sequence into another. In this example the
function object is a member function wrapper which accepts a reference
to a string, invokes the string::length function on it and returns the
result.

A third option is the use of a polymorphic function wrapper
(Boost.Function or tr1::function):

function<void(int)> f = bind1st(&a,mem_fun(&A::f));
f(23); // calls A::f on object 'a' with parameter 23


hope this helps,
SG
 
S

SG

A third option is the use of a polymorphic function wrapper
(Boost.Function or tr1::function):

  function<void(int)> f = bind1st(&a,mem_fun(&A::f));
  f(23); // calls A::f on object 'a' with parameter 23

This should have been

function<void(int)> f = bind1st(mem_fun(&A::f),&a);

instead.


Cheers!
SG
 
J

James Kanze

blackbiscuit wrote:
That depends on you system's memory model.
What's wrong with
typedef void (A::*Fn)(int);
Fn f = A::f;

Perhaps the fact that it won't compile:). You doubtlessly
meant:
Fn f = &A::f ;

More to the point is: what does he mean by "the absolute address
of a.f(int)"? Depending on the system I'm using, I can either
use nm piped to grep, or the linker will generate a map, which
allows me to know the address of any function in the program.
Beyond that, he'll have to explain what he wants before I can
give an answer.
 
M

Michael Doubez

Perhaps the fact that it won't compile:).  You doubtlessly
meant:
    Fn f = &A::f ;

More to the point is: what does he mean by "the absolute address
of a.f(int)"?  Depending on the system I'm using, I can either
use nm piped to grep, or the linker will generate a map, which
allows me to know the address of any function in the program.
Beyond that, he'll have to explain what he wants before I can
give an answer.

An educated guess would be that he wants a kind of closure i.e. being
able to use A::f(int) on instance a as a void (*)(int).

Some C++ compiler vendor provides type for closure and there are
functor implementation (Boost.function) but they cannot be used as a
plain pointer to function.
 
A

Andrew Tomazos

Dear all,

Suppose I have a class A which is defined as follows.

class A
{
    public:
        void f( int i )
        {
        }

};

A a;

How to get the absolute address of a.f( int )? Thank you very much!

Here is our member functor object with 1 parameter that will show you
the syntax for passing, storing and calling a member function:

class Task { public: virtual void execute() = 0; };

template<class C, class F, class P1>
class MethodTask1 : public Task
{
public:
C* m_c; F m_f; P1 m_p1;

MethodTask1(C* c, F f, P1 p1) : m_c(c), m_f(f), m_p1(p1) {}

virtual void execute() { (m_c->*m_f)(m_p1); }
};

template<class C, class F, class P1>
Task* buildMethodTask(C* c, F f, P1 p1) { return new MethodTask1<C, F,
P1>, c, f, p1); }

// called like this:

A a = ...;

Task* task = buildMethodTask(&a, &A::f, 43);

task->execute();

delete(task);

(The real one uses smart pointers, but you get the idea)

Enjoy,
Andrew.
 
B

blackbiscuit

Suppose I have a class A which is defined as follows.
class A
{
public:
void f( int i )
{
}
};
How to get the absolute address of a.f( int )?

What exactly do you mean by absolute address of "a.f(int)"? Can you
elaborate? How would you use such an address? I'm asking because I
think what you want is this:

magic_type p = ...; // address of a.f(int)
p(23); // invoke f(int) on object a

The thing is that member functions are shared accross different
objects of the same class. You have exactly one member function 'f'
for *all* objects of class 'A'. To differentiate between objects a
member function takes an additional parameter (the 'this' pointer)
which is done automatically. What you can do is this:

void (A::*p)(int) = &A::f;
a.*p(23);

In case of data members member pointers are probably just offsets
under the hood. In case of function members member pointers are
probably the absolute address of the function. And these functions
need to know on what object they are working on (implicit 'this'
parameter) which is why you still need to say on what object you'd
like to invoke this member function.

Alternativly you can wrap such a pointer-to-member-function along with
a pointer to an object into a "function object":

auto fun2 = std::mem_fun(&A::f);
fun2(&a,23); // invokes A::f on 'a' with parameter 23

auto fun1 = std::bind1st(fun2,&a);
fun1(23); // invokes A::f on 'a' with parameter 23

Note: The use of 'auto' here for letting the compiler infer the type
is currently not supported by C++. But it's still usable if you pass
the function object to a function template like in this example:

#include <iostream>
#include <ostream>
#include <string>
#include <vector>
#include <functional>
#include <algorithm>

using namespace std;

int main() {
vector<string> sv;
sv.push_back("this");
sv.push_back("is");
sv.push_back("an");
sv.push_back("example");
vector<int> lv (sv.size());
transform( sv.begin(), sv.end(),
lv.begin(),
mem_fun_ref(&string::length) );
for (unsigned k=0, e=lv.size(); k<e; ++k) {
cout << lv[k] << endl;
}
}

std::transform (algorithm header) takes some iterators and a function
object to "transform" one sequence into another. In this example the
function object is a member function wrapper which accepts a reference
to a string, invokes the string::length function on it and returns the
result.

A third option is the use of a polymorphic function wrapper
(Boost.Function or tr1::function):

function<void(int)> f = bind1st(&a,mem_fun(&A::f));
f(23); // calls A::f on object 'a' with parameter 23

hope this helps,
SG

Dear SG,

What I want is as follows.

Now I am developing something by MFC. In MFC, all windows are
represented by a class named as CWnd. But some windows APIs need a
default message process function pointer. In the CWnd, the default
message process function is a member function. So I wanna distill that
member function's address as a parameter of those Windows APIs. So I
ask this question.

Best,
Tony
 
S

Sergey Prokazov

Now I am developing something by MFC. In MFC, all windows are
represented by a class named as CWnd. But some windows APIs need a
default message process function pointer. In the CWnd, the default
message process function is a member function. So I wanna distill that
member function's address as a parameter of those Windows APIs. So I
ask this question.

Best,
Tony


I'm pretty sure you won't need to pass any pointer to object's method
unless it's static.
Non-static methods are useless without pointer to the object known as
"this". So it's gonna be a class static or global callback.
 
S

SG

What exactly do you mean by absolute address of "a.f(int)"? Can you
elaborate? How would you use such an address? I'm asking because I
think what you want is this:

magic_type p = ...; // address of a.f(int)
p(23); // invoke f(int) on object a
[...]

What I want is as follows.

Now I am developing something by MFC. In MFC, all windows are
represented by a class named as CWnd. But some windows APIs need a
default message process function pointer.

I'm not familiar with the Windows API. But I would guess that you can
also specify a pointer (void*, as "context" / "user data") that is
used as additional parameter for the callback. You could use this void
pointer to store a pointer to your class object:

extern "C" { // API header
struct message {
int message_type;
int message_param;
...
};

void register_handler( void(*pfunc)(void*, struct message*),
void* userData );
// somewhere these pointers might be used like this:
// pfunc(userData,...);
}

class MyWindow {
public:
void handle_msg(message* pm);
};

extern "C" {
void mywin_handler_wrapper(void* userData, message* pm) {
static_cast<MyWindow*>(userData)->handle_msg(pm);
}
}

int main() {
Mywindow w;
register_handler(&mywin_handler_wrapper,&w);
...
}


hope this helps,
SG
 
B

blackbiscuit

On 12 Mai, 08:42, blackbiscuit wrote:
How to get the absolute address of a.f( int )?
What exactly do you mean by absolute address of "a.f(int)"? Can you
elaborate? How would you use such an address? I'm asking because I
think what you want is this:
magic_type p = ...; // address of a.f(int)
p(23); // invoke f(int) on object a
[...]

What I want is as follows.
Now I am developing something by MFC. In MFC, all windows are
represented by a class named as CWnd. But some windows APIs need a
default message process function pointer.

I'm not familiar with the Windows API. But I would guess that you can
also specify a pointer (void*, as "context" / "user data") that is
used as additional parameter for the callback. You could use this void
pointer to store a pointer to your class object:

extern "C" { // API header
struct message {
int message_type;
int message_param;
...
};

void register_handler( void(*pfunc)(void*, struct message*),
void* userData );
// somewhere these pointers might be used like this:
// pfunc(userData,...);
}

class MyWindow {
public:
void handle_msg(message* pm);
};

extern "C" {
void mywin_handler_wrapper(void* userData, message* pm) {
static_cast<MyWindow*>(userData)->handle_msg(pm);
}
}

int main() {
Mywindow w;
register_handler(&mywin_handler_wrapper,&w);
...
}

hope this helps,
SG

Hey,

That's a good idea. Thank you very much!

Best,
Tony
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top