2010-07-01 2 views
1

Je crée une DLL C++/CLI gérée qui enveloppe et rend disponible une seule fonction qui réside dans une bibliothèque statique C++. J'ai obtenu la plupart de travail, sauf un point persistant persistante.Comment passer des tableaux gérés par ref à une bibliothèque non gérée?

Voici à quoi ressemble la fonction dans mon fichier .hh lib non managé.

typedef struct 
{ 
    float a; 
    float b; 
}MyStruct; 

bool GetData(float p1, float* p2, MyStruct buffer[]); 

et voici ce que j'ai jusqu'à présent sur l'emballage C++/CLI:

fichier H:

using namespace System::Runtime::InteropServices 

public ref struct MyManagedStruct 
{ 
    float a; 
    float b; 
} 

public ref class Wrapper 
{ 
    bool static GetDataManaged(
     float p1, [Out] float %p2, 
     array<MyManagedStruct^>^managedBuffer); 
} 

fichier CPP:

bool Wrapper::GetDataManaged(
    float p1, [Out] float %p2, 
    array<MyManagedStruct^>^managedBuffer) 
{ 
    float f; 

      //managed buffer is assumed allocated by the .net caller 
    MyStruct* unmanagedBuffer = new MyStruct[managedBuffer->Length]; 

    bool retval = GetData(p1, &f, unmanagedBuffer); 

      /* this doesn't work... any better suggestions? 
    for (int i=0;i<n;i++) 
     BallDatabuffer[i] = buffer[i]; 
      */ 

    p2 = f; 

    return retval; 
} 

Toute aide est appréciée.

Répondre

2

Une façon vous pouvez obtenir les données de votre struct non géré à la struct géré est de déclarer un constructeur pour le struct géré qui accepte une référence à la struct non géré comme ceci:

public ref struct MyManagedStruct 
{ 
    float a; 
    float b; 

internal: 
    MyManagedStruct(const MyStruct &s) 
    { 
     a = s.a; 
     b = s.b; 
    } 
}; 

Notez la visibilité internal: car le constructeur accepte une structure non managée, donc vous ne voulez pas qu'il soit visible de l'extérieur de la DLL C++/CLI.

Avec ce constructeur a déclaré que vous pouvez alors écrire:

bool Wrapper::GetDataManaged(
    float p1, [Out] float %p2, 
    array<MyManagedStruct^>^managedBuffer) 
{ 
    float f; 

    //managed buffer is assumed allocated by the .net caller 
    MyStruct* unmanagedBuffer = new MyStruct[managedBuffer->Length]; 
    int n = managedBuffer->Length; 

    bool retval = GetData(p1, &f, unmanagedBuffer); 

    for (int i=0;i<n;i++) 
     managedBuffer[i] = gcnew MyManagedStruct(unmanagedBuffer[i]); 

    p2 = f; 

    return retval; 
} 
+0

Merci pour la réponse. Après avoir réfléchi un moment à ce qui se passait avec la mémoire, j'ai fini par utiliser gcnew, mais j'ai fait le devoir dans le for {}. –

Questions connexes