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

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

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


Nov 17 '05 #1
Share this Question
Share on Google+
1 Reply


P: n/a

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
"Bern McCarty" <be**********@bentley.com> wrote in message
news:e%****************@tk2msftngp13.phx.gbl...
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

Nov 17 '05 #2

This discussion thread is closed

Replies have been disabled for this discussion.