Dot-Net

如何將 System::array 轉換為 std::vector?

  • March 23, 2020

除了按元素進行之外,還有什麼簡單的方法可以將 CLI/.NET 轉換System::array為 C++嗎?std::vector

我正在SetLowerBoundsWrapper, belowCLI/C++ 中編寫一個包裝方法 ( ),它接受 aSystem::array作為參數,並將等效方法傳遞std::vector給本機 C++ 方法 ( set_lower_bounds)。目前我這樣做如下:

using namespace System;

void SetLowerBoundsWrapper(array<double>^ lb)
{
   int n = lb->Length;
   std::vector<double> lower(n); //create a std::vector
   for(int i = 0; i<n ; i++)
   {
       lower[i] = lb[i];         //copy element-wise
   } 
   _opt->set_lower_bounds(lower);
}

另一種方法,讓 .NET BCL 代替 C++ 標準庫完成工作:

#include <vector>

void SetLowerBoundsWrapper(array<double>^ lb)
{
   using System::IntPtr;
   using System::Runtime::InteropServices::Marshal;

   std::vector<double> lower(lb->Length);
   Marshal::Copy(lb, 0, IntPtr(&lower[0]), lb->Length);
   _opt->set_lower_bounds(lower);
}

以下都使用 VC++ 2010 SP1 為我編譯,並且完全相同:

#include <algorithm>
#include <vector>

void SetLowerBoundsWrapper(array<double>^ lb)
{
   std::vector<double> lower(lb->Length);
   {
       pin_ptr<double> pin(&lb[0]);
       double *first(pin), *last(pin + lb->Length);
       std::copy(first, last, lower.begin());
   }
   _opt->set_lower_bounds(lower);
}

void SetLowerBoundsWrapper2(array<double>^ lb)
{
   std::vector<double> lower(lb->Length);
   {
       pin_ptr<double> pin(&lb[0]);
       std::copy(
           static_cast<double*>(pin),
           static_cast<double*>(pin + lb->Length),
           lower.begin()
       );
   }
   _opt->set_lower_bounds(lower);
}

人為的作用域是讓pin_ptr記憶體盡可能早地unpin,以免阻礙GC。

引用自:https://stackoverflow.com/questions/6846880