【问题标题】:Pointer to managed array in C++/CLI指向 C++/CLI 中托管数组的指针
【发布时间】:2010-08-19 16:06:50
【问题描述】:

好的,我知道你通常会如何声明一个指针:

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

这很好用,除非 managedArray 不包含任何元素。在这种情况下,它会引发 IndexOutOfRangeException。

在 C# 中你可以这样做:

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

即使 managedArray 为空,它也不会访问内存并且可以工作。 我是否真的必须在使用指向托管数组的指针的任何地方检查元素的数量,或者 C++/CLI 是否有办法像 C# 一样做到这一点? 它应该在 ASM 中使用不访问内存的 'lea' 指令。

非常感谢任何帮助!

【问题讨论】:

    标签: c# arrays pointers c++-cli managed


    【解决方案1】:

    当数组为空时,尝试从数组中读取没有多大意义。只需检查一下:

    void SomeFunction(array<float> ^managedArray)
    {
        if (managedArray->Length > 0) {
            pin_ptr<float> managedArrayPtr = managedArray;
            //etc...
        }
    }
    

    【讨论】:

    • 你是对的,但是到处检查很烦人。我希望有一个速记,因为这样的东西在指针语言中经常使用。反正我会用这个。
    • 无处不在?您需要谨慎使用这种代码,固定对垃圾收集器来说是不健康的。
    • 我正在包装一个本地库,我确实在任何地方都使用它。当然,它可能不是真的“无处不在”,但在包装这个库时,无处不在。
    【解决方案2】:

    好问题。不幸的是,我对 C++/CLI 不是很熟悉。我知道您可以使用 GCHandle 结构手动进行固定,并将在空数组上工作。虽然它不如使用pin_ptr 优雅。

    void SomeFunction(array<float> ^managedArray) 
    { 
     GCHandle handle = GCHandle::Alloc(managedArray, GCHandleType::Pinned);
     try 
     {
      float* ptr = (float*)(void*)handle.AddrOfPinnedObject();
     }
     finally
     {
      handle.Free();
     }
    } 
    

    【讨论】:

    • 但是我不妨检查一下长度。我希望有一个快速的方法,比如操作员之类的。
    • 是的,检查长度可能是要走的路。我用谷歌搜索了很多,我也找不到一个优雅的解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-16
    • 2016-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多