2011-07-27 20 views
6

¿Alguien sabe de alguna manera fácil de convertir un CLI/.NET System :: array a un C++ std :: vector, además de hacerlo en cuanto a los elementos?convert System :: array to std :: vector

Estoy escribiendo un método de envoltura (SetLowerBoundsWrapper, a continuación) en CLI/C++ que acepta una matriz System :: como argumento, y pasa el std :: vector equivalente a un método C++ nativo (set_lower_bounds). Actualmente hago esto de la siguiente manera:

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

Respuesta

10

Otro enfoque, dejando que el .NET BCL hacer el trabajo en lugar de la biblioteca de C++ estándar:

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

EDITAR (en respuesta a los comentarios en la respuesta de Konrad):

Los siguientes tanto compilar para mí con VC++ 2010 SP1, y son exactamente equivalentes:

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

(El alcance artificial es para permitir que el pin_ptr desanclar la memoria tan pronto como sea posible, a fin de no obstaculizar el GC.)

+0

Excelente, gracias. Esto funcionó por primera vez – Rory

+1

Para las otras personas que están demasiado ocupadas desplazándose para leer: _opt-> set_lower_bounds (inferior) es la función que viene de la pregunta :) –