2011-07-27 31 views
6

Czy ktoś wie o jakiejkolwiek łatwej drodze do konwersji tablicy systemowej CLI/.NET System do C++ std :: vector, oprócz robienia tego w sposób elementarny?konwersja System :: array na std :: wektor

Piszę metodę wrapper (SetLowerBoundsWrapper, poniżej) w CLI/C++, która akceptuje tablicę System :: jako argument, i przekazuje ekwiwalent std :: vector do natywnej metody C++ (set_lower_bounds). Obecnie zrobić to w następujący sposób:

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); 
} 

Odpowiedz

10

inne podejście, pozwalając .NET BCL wykonać pracę zamiast C++ biblioteki standardowej:

#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); 
} 

EDIT (w odpowiedzi na komentarze na odpowiedź Konrada):

Poniższe obie kompilują się dla mnie z VC++ 2010 SP1 i są dokładnie równoważne:

#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); 
} 

(Sztuczna zakres jest umożliwienie pin_ptr odpiąć pamięci tak wcześnie jak to możliwe, tak, aby nie utrudniać GC).

+0

doskonała, dzięki. To zadziałało po raz pierwszy – Rory

+1

Dla innych ludzi, którzy są zbyt zajęci przewijaniem, aby przeczytać: _opt-> set_lower_bounds (lower) to funkcja, która pochodzi z pytania :) –