将数据从非托管代码传递到托管代码

时间:2015-05-05 22:41:15

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

我有一个三层应用程序:

  1. 托管的c#层。
  2. 托管c ++ / cli图层。
  3. 非托管c ++层。
  4. 第二层用作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?

1 个答案:

答案 0 :(得分: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