Declaring and using __gc pointers to native structs [MEC++ - VC 7.1]

B

Bern McCarty

I am using MEC++ in VC 7.1. I had a method on a __gc object that looked
like this:

__property System::UInt32 get_MyProperty(void)
{
System::Byte __pin * pinBytes = &m_byteArray[0]; // entire array is
now pinned
NativeStruct const __nogc* nativeStructP = reinterpret_cast<NativeStruct
const __nogc*>(pinBytes);

return nativeStructP->myField;
}

Then I made another version of the property that didn't do any pinning.
Instead this version cast the address the first element of the managed byte
array member to a managed pointer to a native class like so:

__property System::UInt32 get_MyPropertyNoPin(void)
{
NativeStruct const __gc* nativeStructP= reinterpret_cast<NativeStruct
const __gc*>(&m_byteArray[0]);

// what happens if the heap is compacted right here? Am I guaranteed to
be OK when I dereference nativeStructP below since I'm using a __gc pointer?

return nativeStructP->myField;
}

It seems to compile and run just fine. Can I really create tracking
references to native structs that, through pointer casting, really live in
the managed heap? Will they track correctly if the heap is compacted? Or
is this just a crash waiting to happen?

I actually didn't even expect this to compile. I would have thought that
even declaring a __gc pointer to a __nogc type would result in a
compile-time error. That it does compile and seems to run has me wondering
if it will actually work reliably. If so, then it means that I can avoid
pinning much more than I thought that I could.

If this will work, will it still be possible to do this in C++/CLI in VC 8?

-Bern
 
B

Bern McCarty

I realized after looking at the ILDASM output of the result of this that the compiler wasn't really
generating managed pointers where I was asking it to. This seems like a bad bug. I thought the
only way to convert a managed pointer to an unmanaged pionter was supposed to be via pinning. This
appears to be a hole in the enforcement of that rule. When I do:

NativeStruct const __gc* nativeStructP= reinterpret_cast<NativeStruct const
__gc*>(&m_byteArray[0]);

....nativeStructP is not REALLY a managed pointer if you look at the resulting IL. Rather it is an
unmanaged pointer. And the compiler does not complain about this code at all. It just merrily
ignores the __gc keyword.

-Bern
 

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