views:

28

answers:

2

Alright, I know how you normally would declare a pointer:

void SomeFunction(array<float> ^managedArray)
{
  pin_ptr<float> managedArrayPtr = &managedArray[0];
}

This works fine except when managedArray contains no elements. In that case, it throws an IndexOutOfRangeException.

In C# you can do this:

void SomeFunction(float[] managedArray)
{
  fixed (float* managedArrayPtr = managedArray)
  {
  }
}

Which does no memory access and works even if managedArray is empty. Do I really have to check for the number of elements everywhere I use pointers to managed arrays or does C++/CLI have a way to do it like C#? It should be using the 'lea' instruction in ASM which does no memory access.

Any help is greatly appreciated!

A: 

Good question. Unfortunately I am not that familiar with C++/CLI. I do know that you can do the pinning manually using the GCHandle struct and will work on empty arrays. It is not as elegant as using pin_ptr though.

void SomeFunction(array<float> ^managedArray) 
{ 
 GCHandle handle = GCHandle::Alloc(managedArray, GCHandleType::Pinned);
 try 
 {
  float* ptr = (float*)(void*)handle.AddrOfPinnedObject();
 }
 finally
 {
  handle.Free();
 }
} 
Brian Gideon
But then I might as well just check the length. I was hoping for a quick way, like an operator or something.
Yeah, checking the length is probably the way to go. I googled quite a bit I could not find an elegant solution either.
Brian Gideon
+1  A: 

There isn't much point in trying to read from the array when it is empty. Just check for that:

void SomeFunction(array<float> ^managedArray)
{
    if (managedArray->Length > 0) {
        pin_ptr<float> managedArrayPtr = managedArray;
        //etc...
    }
}
Hans Passant
You're right, but it's annoying to check that everywhere. I was hoping for a shorthand since something like this is used very often in pointer languages. Anyways I'll use this.
*Everywhere*? You need to use this kind of code sparingly, pinning isn't healthy for the garbage collector.
Hans Passant
I'm wrapping a native library and I do indeed use it everywhere. Sure, it might not really be 'everywhere' generally, but while wrapping this library, yes everywhere.