Class member method

M

MacFly

Hi everyone,

HRESULT WINAPI DirectPlayMessageHandler( PVOID pvUserContext, DWORD
dwMessageId, PVOID pMsgBuffer)

I want that method to be class member method so it could have access to
class variables, but don't know how to do it ?
I still receive errors when I try to use it.


Thanks in advance for help.
Regards.
 
J

Jonathan Turkanis

MacFly said:
Hi everyone,

HRESULT WINAPI DirectPlayMessageHandler( PVOID pvUserContext, DWORD
dwMessageId, PVOID pMsgBuffer)

I want that method to be class member method so it could have access to
class variables, but don't know how to do it ?
I still receive errors when I try to use it.

This is off-topic, since the you're using a number of
platform-specific macros. A good group to post to would be
microsoft.public.dotnet.languages.vc.

However, I think you will find that you can make the function a static
member without error.

Jonathan
 
J

Julie

On the contrary, this is not at all off topic.

The basic question is how to associate an instance of a class through c-style
callbacks.

I'm not sure about the specifics of the callback, but it looks like the
pvUserContext could be used to hold the instance of your class (cast as a void
pointer). If that is the case, then simply pass in the instance of your class
to the routine that initially takes the pvUserContext variable, then in the
context of the DirectPlayMessageHandler, simply cast the pvUserContext to a
pointer of your class type and go from there.

Something like this

Initialize_Function((void *)&your_class_instance, DirectPlayMessageHandler, /*
etc */);

// ...

HRESULT WINAPI DirectPlayMessageHandler( PVOID pvUserContext, DWORD
dwMessageId, PVOID pMsgBuffer)
{
your_class_type * pointer_to_your_class_instance = (your_class_type
*)pvUserContext;
pointer_to_your_class_instance->method1(); // or whatever methods you want to
call
// etc.
}

Get it?
 
J

Jonathan Turkanis

Julie said:
On the contrary, this is not at all off topic.

The basic question is how to associate an instance of a class through c-style
callbacks.

I think the OP's problem was that he or she wanted to give the
callback function access priviledges by making it a member, but was
getting errors because win32 callback functions can't be a non-static
members. That's why I said it's off topic.

Your example involved the code

HRESULT WINAPI DirectPlayMessageHandler
( PVOID pvUserContext, DWORD dwMessageId, PVOID pMsgBuffer)
{
// ...
pointer_to_your_class_instance->method1();
// ..
}

What if method1 is private? That's the problem the OP was trying to
solve.

I think so; do you?

Jonathan
 
D

David White

Jonathan Turkanis said:
I think the OP's problem was that he or she wanted to give the
callback function access priviledges by making it a member, but was
getting errors because win32 callback functions can't be a non-static
members. That's why I said it's off topic.

I don't think access privileges have anything to do with it. The problem is
the general one of how to get a callback function to belong to an instance
of a class when its type is that of an ordinary external or static function.
This cannot be done directly by making the function a non-static member,
since the function won't be called in the context of a class instance.
Your example involved the code

HRESULT WINAPI DirectPlayMessageHandler
( PVOID pvUserContext, DWORD dwMessageId, PVOID pMsgBuffer)
{
// ...
pointer_to_your_class_instance->method1();
// ..
}

What if method1 is private? That's the problem the OP was trying to
solve.

I don't think so. Obviously, if method1 is private you would not call it.
You'd call another function that is public, or you'd make method1 public so
you can call it.
I think so; do you?

No. Before worrying about access rights, you have to get at the class
instance from the external function in the first place. I believe the OP
only wants to know how to somehow get into a non-static member function when
the callback is called.

DW
 
J

Jonathan Turkanis

David White said:
I don't think access privileges have anything to do with it. The problem is
the general one of how to get a callback function to belong to an instance
of a class when its type is that of an ordinary external or static function.
This cannot be done directly by making the function a non-static member,
since the function won't be called in the context of a class
instance.

Okay, both of these are well known problems with familiar solutions.
It's just a matter of figuring out what the OP meant.

What struck me about the original message is that the OP wanted the
callback function to access 'class variables'. That's why I focused on
access privileges. On the other hand, the OP may have been trying to
solve the more basic problem 'how do I get ahold of a class instance'?

I think all of us who have responded to the thread know how to solve
both problems. Only the OP knows what was originally intended.

Jonathan
 
J

John Harrison

MacFly said:
Hi everyone,

HRESULT WINAPI DirectPlayMessageHandler( PVOID pvUserContext, DWORD
dwMessageId, PVOID pMsgBuffer)

I want that method to be class member method so it could have access to
class variables, but don't know how to do it ?
I still receive errors when I try to use it.

Bad news, it can't be a class member method, it must be a free function.

Good news, but see that pvUserContent parameter? It could be a pointer to
your object. Assuming your class is called MyClass then

HRESULT WINAPI DirectPlayMessageHandler( PVOID pvUserContext, DWORD
dwMessageId, PVOID pMsgBuffer)
{
return ((MyClass*)pvUserContent)->DirectPlayMessageHandler(dwMessageId,
pMsgBuffer);
}

Now all you have to do is set things up so that pvUserContext points to the
object you are interested in, but that is a function of the WIN32 API so off
topic here.

This is covered in the FAQ (not very well tho' IMHO)

http://www.parashift.com/c++-faq-lite/pointers-to-members.html

john
 
M

MacFly

Thanks for all replies and I'm sorry I didn't explain my problem more
precisely.

I just wanted to have access to class variables in DirectPlayMessageHandler
method, so I wanted to be class member function. Now I know it has to be
static.

But I'm still confused about the procedure of associating an instance of a
class described by Julie. what is the difference between
"your_class_instance" and "your_class_type" ??

How should it look like in my case:

class CConnection
{
.....
};

The function I use to initialize:
hr = m_pDP->Initialize(NULL, DirectPlayMessageHandler, 0 ) )

so what should be put in the place of NULL ?

Regards.
 
M

MacFly

To John Harrison:
I guess we posted our messages at the same time :) So I read yours after I'd
posted mine.
 
J

Julie

your_class_type is a placeholder for the class type, in this case CConnection.

your_class_instance is a placeholder for an instance of CConnection. I don't
know what you called it in your code.

Here is an example:

class CConnection
{
private:
HRESULT DirectPlayMessageHandler(DWORD dwMessageId, PVOID pMsgBuffer);

public:
static HRESULT WINAPI Thunk_DirectPlayMessageHandler(PVOID pvUserContext,
DWORD dwMessageId, PVOID pMsgBuffer)
{
return ((CConnection *)pvUserContext)->DirectPlayMessageHandler(dwMessageId,
pMsgBuffer);
}
// etc.
};



// in your code somewhere
CConnection * connection = new CConnection();

hr = m_pDP->Initialize((void *)&connection,
CConnection::Thunk_DirectPlayMessageHandler, 0 );


//etc.

Here's how it works:

Add to your class a static thunk method with the same signature as the DPMH but
that is static. All that this method does is simply take ther user context,
cast it to the type of your class, and then call a non-static method on that
class.

When you initialize, you pass in the address of the instance of your class that
you want to act on, connection in this case, and the address of the thunk
function.

Now, when the code is executed, the internal workings calls the thunk function
w/ the instance of your class, which is cast and makes the method call on the
full member DirectPlayMessageHandler, which has full access to all class
methods/data.

Dig?
 
M

MacFly

I think I understand but there is still one thing which I have to handle
with.
When you initialize, you pass in the address of the instance of your class that
you want to act on, connection in this case, and the address of the thunk
function.

I need this function to initialize object:
IDirectPlay8Peer* m_pDP;
which is other class member. What is more I want initializing that obejct in
other class method:

HRESULT CConnection::InitializeDirectPlay()
{
....
m_pDP->Initialize((NULL, DirectPlayMessageHandler, 0 ) )
....
}

So how can I pass in the address of the instance class ?
 
J

Julie

I need this function to initialize object:
IDirectPlay8Peer* m_pDP;
which is other class member. What is more I want initializing that obejct in
other class method:

HRESULT CConnection::InitializeDirectPlay()
{
....
m_pDP->Initialize(this, Thunk_DirectPlayMessageHandler, 0);
....
}
 

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

No members online now.

Forum statistics

Threads
474,163
Messages
2,570,897
Members
47,435
Latest member
PhilipBelm

Latest Threads

Top