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

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

我有一个三层应用程序:

  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?

最佳答案

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

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

使用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

关于c# - 将数据从非托管代码传递到托管代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30064439/

相关文章:

c++ - 部分函数/方法模板特化解决方法

c++ - 从 C++ 中的基调用潜在 child 的构造函数

.net - D8045 : cannot compile C file 'serialcommands.c' with the/clr option

c# - 包装托管代码以供非托管使用

c++-cli - 是否需要AssemblyInfo.cpp?

c# - 如何在 WPF C# 应用程序中动态添加复选框

c# - 如何在 C# 中使用 system.drawing 将居中文本绘制到 jpg 上

c# - 如何使用 NUnit 中的指定容差比较 double ?

c++ - 如何在 C++ 中定义采用两个迭代器的模板函数?

c# - Entity framework Profile Provider example..如何初始化和设置请帮忙!