如何在我的 .NET 类中使用这个原生数组?

Posted

技术标签:

【中文标题】如何在我的 .NET 类中使用这个原生数组?【英文标题】:How do I use this native array in my .NET class? 【发布时间】:2010-12-14 11:28:28 【问题描述】:

我正在使用 .NET 和 WPF 更新本机 (MFC) 应用程序的 GUI。该应用程序实时收集数据,并且 GUI 应该(实时)可视化该数据。总体计划是使用 C++/CLI 作为原生应用程序和托管 GUI 部分之间的互操作层。

我有一个包含字节数组的本地类,其中包含一个“标题”,该标题给出了数组的长度和其中元素的类型。我正在尝试在 C++/CLI 中编写此本机类和托管 .NET 类之间的互操作性层。

我想在应用程序的托管部分使用非托管字节数组。各种博客和文档中心的信息让我有些不知所措。这是我到目前为止所得到的概要,它有点工作但有时会崩溃*。我不确定这是否是最合适的解决方案,甚至不确定如何正确实施。我想知道是否有更合适的方法?

// Fetch numbers from the native class into unmanaged memory.
IntPtr ipNumbers = InteropServices::Marshal::AllocHGlobal(sizeof(int) * arrayLength))
nativeClass->fetchNumbers((int *) ipNumbers.ToPointer(), arrayLength);

// Copy data from unmanaged memory into a managed array.
cli::array<int, 1> ^numbers = gcnew cli::array<int, 1>(arrayLength);
InteropServices::Marshal::Copy(ipNumbers, numbers, 0, arrayLength);
InteropServices::Marshal::FreeHGlobal(ipNumbers);

*) 崩溃消息:“Windows 已在 MyProgram.exe 中触发断点。这可能是由于堆损坏,这表明 MyProgram.exe 或其已加载的任何 DLL 中存在错误。[.. .]”。据我所知,导致崩溃的是FreeHGlobal

【问题讨论】:

您的代码看起来不错,我不知道为什么如果没有看到更多代码就会导致崩溃。您可以通过使用 pin_ptr 到 numbers 数组并将其直接传递给 fetchNumbers 来避免分配非托管内存。 我将代码改为使用 pin_ptr 数字,这似乎可行。 (我会用代码更新我的帖子。):-D 我想我唯一需要知道的是这是否是最好的方法。 【参考方案1】:

考虑到 Mattias 的建议,我更改了代码,现在可以正常工作了。

cli::array<int, 1> ^numbers = gcnew cli::array<int, 1>(arrayLength);
pin_ptr<int> pp = &numbers[0];
nativeClass->fetchNumbers(pp, arrayLength);

【讨论】:

以上是关于如何在我的 .NET 类中使用这个原生数组?的主要内容,如果未能解决你的问题,请参考以下文章

我如何在我的异步任务类中使用圆形旋转进度条

如何从 socket.io 获取原生事件数组?

如何在我的 UIViewController 类中声明 UIImageView 以便其他类可以使用它?

如何将此对象存储在我的 iOS 类中?

如何检查在 C# 的全局类中找到的数组中是不是存在对象

如何访问类对象内的数组值?