【问题标题】:How to Resize an Array defined as: gcroot<array<double> ^>如何调整定义为的数组大小:gcroot<array<double> ^>
【发布时间】:2018-03-14 08:02:51
【问题描述】:

使用带有CLR 选项的 Microsoft C++。 我使用 gcroot 来定义非托管类中数组的托管句柄​​。

Microsoft gcroot 示例请参见下面的链接。

gcroot < array<double> ^ >  xArray;

然后我使用 gcnew 来分配数组。

myClass.xArray = gcnew array<double>(scanProp.nz);

这行得通,我可以根据需要通过传递给第 3 方库托管函数来使用该数组。

问题:之后如何调整数组的大小?

System::Array::Resize 不接受 gcroot 数组。

我想过用同样的“Array”变量再次调用gcnew,让垃圾回收器释放之前的数组。

问题:

如果 gcnew 被同一个变量调用两次会发生什么?

第一次调用释放内存了吗?

示例:

myClass.xArray = gcnew array<double>(100);

myClass.xArray = gcnew array<double>(1000);

如图所示:https://docs.microsoft.com/en-us/cpp/dotnet/how-to-declare-handles-in-native-types#see-also

【问题讨论】:

  • 必须访问托管数组的非托管代码是一种非常重的代码气味。但可以肯定的是,您必须重新分配它,因为 Resize() 必须创建一个新的数组对象。 GC 负责清理战利品,不需要或不需要任何帮助。

标签: arrays class c++-cli managed


【解决方案1】:

标准警告:当然可以用 C++/CLI 编写应用程序的主体,甚至可以使用 WinForms 用 C++/CLI 编写 GUI,但不建议这样做。 C++/CLI 旨在用于互操作场景:在 C# 或其他 .Net 代码需要与非托管 C++ 交互的情况下,C++/CLI 可以提供两者之间的转换。因此,C++/CLI 具有 C++ 的所有复杂性、C# 的所有复杂性,以及它自己的一些复杂性。对于初级开发,如果您想要托管代码,建议使用带有 WinForms 或 WPF 的 C#,或者如果您想要非托管代码,则建议使用带有 MFC 的 C++。


首先,.Net 数组不存在真正的“调整大小”。根据定义,.Net 数组具有一种在创建时固定的大小。 Array::Resize 方法实际上是创建一个具有所需大小的新数组,并将所有数据从旧数组复制到新数组。

它不允许您使用gcroot 调用Array::Resize,因为Resize 采用跟踪引用参数(C# 中的ref,C++/CLI 中的^%)。

您可以获取gcroot,将其复制到本地(非gcroot)变量,在其上调用Array::Resize,然后将其重新分配给gcroot

gcroot<array<double>^> xArray;

int newsize = ...;

array<double>^ temp = xArray;
Array::Resize(temp, newsize);
xArray = temp;

不过,Array::Resize 所做的并没有什么特别之处,你可以自己做。

gcroot<array<double>^> xArray;

int newsize = ...;

array<double>^ newArray = gcnew array<double>(newsize);
Array::Copy(xArray, 0, newArray, 0, Math::Min(xArray->Length, newsize));
xArray = newArray;

【讨论】:

  • 这很好用。谢谢 !请注意,我使用的是带有 MFC 的 C++,以及一个带有 C++ API 接口的托管图形库。
猜你喜欢
  • 2020-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-27
  • 2020-07-09
  • 2014-05-22
  • 2015-02-04
  • 1970-01-01
相关资源
最近更新 更多