Miscellaneous Debris

Avner Kashtan's Frustrations and Exultations

A C# coder in a C++/CLI world, part 1

Recently I've found myself stumbling around some C++/CLI code. C++ is a language which I learned years ago and never really worked with seriously, so I've been cursing and moaning as I worked. Strange for me to go back to a (partially) unmanaged environment now, with all sorts of assumptions that I have proven to be false. I'll try to go over some pitfalls and insights I'm having during the visit. This is the first:

The Garbage Collector really spoiled me. I'm not talking about deleting what I instantiated, but all sorts of subtler bugs related to going out of scope. For instance, I had code like this that receives a managed, .NET byte[] and turns it into an unmanaged char*:

void DoSomething(array<Byte>^ data)
{
   
   // Pin the managed array to an unmanaged char*.
   pin_ptr<Byte> pinnedBuffer = &data[0];
   char* buffer = (char*)pinnedBuffer;      

   // Now do something with the unmanaged buffer.
}

Simple enough, but then I found myself needing it in a different method too. My first instinct, of course, is refactor those two lines into a new method to do the array conversion, especially since I had a couple of lines of parameter validation there too. But my new GetUnmanagedBuffer(array<Byte>^) method wasn't as simple as I hoped. This is because the pinnedBuffer object that I created to prevent the GC from moving the managed array went out of scope when the method exited, and by the time I used the buffer in my unmanaged code, the data wasn't sure to be there anymore.

In the managed world, we're used to one of two scenarios when returning function parameters: either's a value type that's copied completely, or a reference type that passes a managed, GCed reference. In both these cases, we know that returning any object from a method is a safe operation.

Additonally, we in managed land are used to refactoring being a safe operation, in most cases. If I don't have to worry about scope, I don't worry about extracting any block of code into its own method. In C++, however, I have this constant uncertainty. It will pass with exprience, but I still feel much less safe than I would moving to a different, managed environment.

 

This was the first installment of Tales from the Unmanaged Side. I'll see if I have anything else to say the more I work on this

Posted: Aug 28 2007, 04:48 PM by Avner Kashtan | with 5 comment(s)
Filed under: , ,

Comments

Nish said:

Yes, the scenario you describe is sometimes called a GC hole :-)

Typically caused by bad code that returns a pointer to a pinned object (and when pinning ends - boom!)

# August 28, 2007 11:19 AM

Glenn Slayden said:

You can use a GCHandle to pin it beyond the scope.

# August 19, 2009 10:34 PM

weblogs.asp.net said:

A c coder in a c cli world part 1.. Amazing :)

# May 19, 2011 8:02 AM