Passing managed object reference to unmanaged code

G

Guest

Hello,

I have some legacy unmanaged C++ code in which I've introduced some managed
C++ using the new CLI feature of VS 2005. My managed C++ code invokes a
number of methods on a new C#class I've written. This C# class creates
additional managed objects and passes one of them back to the managed C++
code. I believe I have everything right to this point.

I need to briefly pass the managed object into unmanaged C++ code before
returning to managed C++ code. I want to make sure I do this correctly;
although the amount of time the object is passed into the unmanaged code is
very short, I don't want my managed object to get accidentally garbage
collection. I've looked at the MSDN documentation, and the suggestion seems
to be to use gcroot or GCHandle. However, in my case the managed object is
being instantiated in C#, not C++, so that's not an option. Is there any
other way I could be sure by object won't be garbage collected or relocated?

Thanks,
Notre
 
T

Tamas Demjen

Notre said:
I've looked at the MSDN documentation, and the suggestion seems
to be to use gcroot or GCHandle. However, in my case the managed object is
being instantiated in C#, not C++, so that's not an option.

Yes, it is. The C++ gcroot<> is just a wrapper around GCHandle. I think
you can call GCHandle::Alloc() from C#. Just don't forget to call
GCHandle::Free() for it when you no longer need to lock the instance.

Tom
 
S

SvenC

Hi,

Notre Poubelle said:
Hello,

I have some legacy unmanaged C++ code in which I've introduced some
managed
C++ using the new CLI feature of VS 2005. My managed C++ code invokes a
number of methods on a new C#class I've written. This C# class creates
additional managed objects and passes one of them back to the managed C++
code. I believe I have everything right to this point.

I need to briefly pass the managed object into unmanaged C++ code before
returning to managed C++ code. I want to make sure I do this correctly;
although the amount of time the object is passed into the unmanaged code
is
very short, I don't want my managed object to get accidentally garbage
collection. I've looked at the MSDN documentation, and the suggestion
seems
to be to use gcroot or GCHandle. However, in my case the managed object
is
being instantiated in C#, not C++, so that's not an option. Is there any
other way I could be sure by object won't be garbage collected or
relocated?

I never tried it but why should gcroot not work?

gcroot<YourCSharpClass^> passMyToNative = mngdClass->ReturnACSharpObject();
 
G

Guest

I think I was confused here. Please correct me if I'm wrong (again):

Even though my object is allocated on the managed stack in C#, when it gets
passed to C++ I should be able to use GCHandle (or gcroot) before calling the
unmanaged function in C++. Does that sound right?
 
C

Carl Daniel [VC++ MVP]

SvenC said:
I never tried it but why should gcroot not work?

gcroot<YourCSharpClass^> passMyToNative =
mngdClass->ReturnACSharpObject();

Yes - That's the correct solution. You can pass the gcroot<T> object
through as much native code as you want, pulling the managed object
reference back out when you need to call into the managed object.

-cd
 
G

Guest

So just to be clear, could I safely write code like this:

C# code:

MyObject obj = new MyObject();
CPPObject.DoStuff(obj);

C++ (managed):

void CPPObject::DoStuff(MyObject^ theObject)
{
IntPtr handle = static_cast<IntPtr>(GCHandle::Alloc(theObject));
NativeFunction(handle);
static_cast<GCHandle>(handle).Free();
}

C++ (unmanaged):

void NativeFunction(LPARAM param)
{
//Do stuff, including calling back into managed code
}
 
A

Arnaud Debaene

Notre Poubelle said:
So just to be clear, could I safely write code like this:
<snip>
Yes you can! What don't you just try it???

The source langage is irrelevant in .NET. At run time, all what you get is a
reference to a managed object allocated on the managed heap. The source
could be written in managed C++, VB.NET, C# or any other, it doesn't make
any difference since all those are compiled to the same MSIL.

Arnaud
MVP - VC
 
G

Guest

Yes, Arnaud I do intend to try this. The thing is, it's not immediately
obvious if I'm doing things right since garbage collection is not especially
predictable so things might 'look' like they're working but in fact will fail
in production. That's why I'm trying to explain what I plan to do with the
experts (you guys!) to see if you can spot any holes in what I'm doing.

Notre
 

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