Pinning a managed object that is being used for a unmanged callback

M

Maxwell

Hello,

Newbie question here. I have a VS.NET 2003 MC++ (not C++/cli) project
where I have a managed class reference in a unmanaged class...simple
enough. To keep things short I am for the most part attempting to do
what is this article by Nish:
http://www.voidnish.com/articles/ShowArticle.aspx?code=cbwijw

I have to hook up a unmanaged callback to a managed method using IJW
NOT P\Invoke. So I am employing this "Thunk" or "Bridge" class as I
think it is called.

Based on what I have read so far (aka very limited understanding)
anytime one is accessing a managed object in a managed class one would
"pin it". However in the code snippet:

....snip

// Unmanged code
static BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM)
{
// We need to get the managed callback
// up for each instance that our callback
// gets called. So we get a pointer to
// the current instance of the outer class
// and invoke the delegate that is holding
// the managed callback method that the
// callee code has passed to us
CEnumWindows* pew = CEnumWindows::GetClass();
//CEnumWindows is a managed C++ class
pew->m_EnumProc->Invoke(hwnd, NULL);
return TRUE;
}

....snip


I see a reference to get a pointer to the managed object->
CEnumWindows* pew = CEnumWindows::GetClass()" but I dont see a __pin *
or gcroot<CEnumWindows*>pew. Before its being Accessed? Is this because
the the pointer that GetClass() returns is static?

This code is getting called by my unmanaged C++ class at least 10-20
times a second so I wanted to make sure that:

1) Its safe to do this (code above: pew->m_EnumProc->Invoke(hwnd,
NULL);) without pinning the pointer to the managed class?

2) if I did change the code to:

// Unmanged code
static BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM)
{
// We need to get the managed callback
// up for each instance that our callback
// gets called. So we get a pointer to
// the current instance of the outer class
// and invoke the delegate that is holding
// the managed callback method that the
// callee code has passed to us
gcroot<CEnumWindows*>pew = CEnumWindows::GetClass();
pew->m_EnumProc->Invoke(hwnd, NULL);
return TRUE;
}

Is this correct or completely overkill?

3) Since this callback is being called quite intensively by my
application, If pinning is actually required in this case or if its
safer to pin but not required kind of thing. Is it better performance
wise to do something like pinning (or gcrooting it) the entire object
in the unmanaged clas like so:

namespace UnmanagedLib
{
class UClass
{

private:
gcroot<ManagedClass *> pew;

.... snip

static BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM)
{
pew->m_EnumProc->Invoke(hwnd, NULL);
return TRUE;
}


public:
UClass(ManagedClass *pMClass) : pManagedClass(pMClass)
{
pew = pMClass
}

~UClass()
{

}

....snip
};

Is this just bad practive to pin a entire managed object for the life
of my application process and also on a complete newbie side bar If I
dont have something in the destructor do I have a gcroot leak?
 
M

Maxwell

Update post sorry:

This:

Based on what I have read so far (aka very limited understanding)
anytime one is accessing a managed object in a managed class one would
"pin it".

Should read

Based on what I have read so far (aka very limited understanding)
anytime one is accessing a managed object in a _unmanaged_ class one
would
"pin it".
 
N

Nishant Sivakumar

Hello Maxwell

Oh btw, I am the "Nish" who authored that article :)

The reason you don't need to pin that pointer is that pew is a CEnumWindows*
(an __gc*) - so if the object pointed to by m_pclass is moved around the CLI
heap, it doesn't matter because the __gc* will be automatically updated
(it's not a native pointer - it's a tracking pointer that actually tracks
the object it points to).

Hope this makes sense.
 
M

Maxwell

Wow, how cool is that...:) Your article helped me out so much, thanks
BTW :)

Well that explains lot I think I get it, I think I missed the fact that
it was a managed class in the sample. Just one note then on this, if
it is a managed pointer in unmanged code how come you didn't have to
use gcroot<CEnumWindows *>?

Thanks Again
Max
 
N

Nishant Sivakumar

Hello Max,

You can instantiate and use __gc pointers from functions of __nogc classes.
You only need to use gcroot when you want to have an __gc member in an
__nogc class.
 

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

Top