【问题标题】:Passing data from Unmanaged code to managed code将数据从非托管代码传递到托管代码
【发布时间】:2015-05-05 22:41:15
【问题描述】:

我有一个三层的应用程序:

  1. 托管的 c# 层。
  2. 托管的 c++/cli 层。
  3. 非托管 c++ 层。

第二层用作c#和native c++之间的通信层。

public class ManagedResult
{
  public float[] firstArray;
  public float[] secondArray;
}

和非托管类

 class UnmanagedResult
    {
      public:
         float* firstArray, secondArray;
         int arrayLength;
         UnmanagedResult(){};
         ~UnmanagedResult(){};
    }

我在第二层有一个类的以下方法,它输出一个托管对象:

 ManagedResult^ CLIContext::GetResults(){

   ManagedResult^ primitiveResult = gcnew ManagedResult();

   pin_ptr<int> pFirst = &(primitiveResult->firstArray[0]);
   pin_ptr<float> pSecond = &(primitiveResult->secondArray[0]);
   UnmanagedResult result =UnmanagedResult();
   result.firstArray = pFirst;
   result.secondArray = pSecond;

   _context->GetResults(result);

   return primitiveResult;

 }

这里的 _context 是一个非托管类类型的对象,它操纵一个 UnmanagedResult 类型的对象并影响其内容。

此解决方案运行良好。但我希望能够通过引用对象和第三方 API 来分配和填充两个成员 firstArraysecondArray。 如何将数据从非托管结果传输回primitiveResult?

【问题讨论】:

  • 对于非托管到托管,您需要一个单独的变量来保存项目计数 - 您能提供吗?此外,您必须复制 数组内容,因为很遗憾,您不能将托管数组放在现有数据之上。你可以吗?
  • 是的,我可以提供其中的项目数。我很感兴趣如何以最快的方式将数组内容从一层复制到另一层。
  • 好吧,如果你想尽可能快,那就不要复制。您可能希望从包装该 3rd 方 api 的任何 ref 类包装器返回 IntPtr 并在此再次转换为 (float*)。

标签: c# c++ c++-cli interop native-code


【解决方案1】:

由于非托管数组只是指向其第一项的指针,因此您需要知道项数。

如果您想要一个托管数组,则必须创建一个并将数据复制到那里。您将无法创建指向现有非托管内存的托管数组。

为此使用System::Runtime::InteropServices::Marshal::Copy

UnmanagedResult unmanagedResult = GetTheUnmanagedResultSomehow();
ManagedResult^ managedResult = gcnew ManagedResult();

managedResult->firstArray = gcnew array<float>(unmanagedResult.arrayLength);
Marshal::Copy(IntPtr(unmanagedResult.firstArray), managedResult->firstArray, 0, managedResult->firstArray->Length); 

// Do the same for secondArray

【讨论】:

    猜你喜欢
    • 2011-11-01
    • 2011-09-06
    • 2013-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-27
    • 2013-08-24
    • 2011-01-21
    相关资源
    最近更新 更多