By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,617 Members | 1,591 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,617 IT Pros & Developers. It's quick & easy.

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

P: n/a
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/Sho...px?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?

Nov 23 '05 #1
Share this Question
Share on Google+
5 Replies


P: n/a
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".

Nov 23 '05 #2

P: n/a
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.

--
Regards,
Nish [VC++ MVP]
"Maxwell" <rb*@dslextreme.com> wrote in message
news:11**********************@o13g2000cwo.googlegr oups.com...
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/Sho...px?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?

Nov 25 '05 #3

P: n/a
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

Nov 26 '05 #4

P: n/a
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.

--
Regards,
Nish [VC++ MVP]
http://www.voidnish.com
http://blog.voidnish.com
"Maxwell" <rb********@gmail.com> wrote in message
news:11********************@g47g2000cwa.googlegrou ps.com...
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

Nov 27 '05 #5

P: n/a
Ah, now I see. Once Again Thanks much for the help...and the article :)!

Nov 28 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.