Domanda

Ho una funzione in C # che sta passando una matrice di strutture in una DLL scritta in C ++. La struct è un gruppo di int e quando ho letto i dati nella DLL tutti i valori escono bene. Tuttavia, se provo a scrivere agli elementi da C ++ i valori non appaiono quando provo a leggere poi di nuovo in C #.

C #

[StructLayout(LayoutKind.Sequential)]
struct Box
{
  public int x;
  public int y;
  public int width;
  public int height;
}

[StructLayout(LayoutKind.Sequential)]
struct Spot
{
  public int x;
  public int y;
}

static void TestCvStructs()
{
  int len = 100;
  Box[] r = new Box[len];
  Spot[] p = new Spot[len];

  for (int i = 0; i < len; i++)
  {
    r[i].x = i*10;
    r[i].y = i * 200;
    r[i].width = r[i].x * 10;
    r[i].height = r[i].y * 100 + r[i].x * 5;

    p[i].x = i * 8;
    p[i].y = i * 12;
  }

  PassCvStructs(len, r, p);

  for (int i = 0; i < len; i++)
  {
    Console.WriteLine("Point/x:{0} Boxes/x{1}", p[i].x, r[i].x );
  }
}

[DllImport(dll)]
private static extern int PassSomeStructs(int count, Box[] boxes, Spot[] points);

C ++

typedef struct Box
{
  int x;
  int y;
  int width;
  int height;
} Box;

typedef struct Spot
{
  int x;
  int y;
} Spot;

CPPDLL_API int PassSomeStructs(int arrayLength, Box *boxes, Spot *points)
{
  for(int i = 0; i < arrayLength; ++i)
  {
    printf("Group:%i\n", i);
    printf("Rect - x:%i y:%i width:%i length:%i\n", boxes[i].x, boxes[i].y, boxes[i].width, boxes[i].height);
    printf("Point - x:%i y:%i\n", points[i].x, points[i].y);
    printf("\n");

    points[i].x = 3;
    boxes[i].x = 1;
  }
  return 0;
}
È stato utile?

Soluzione 3

Ho trovato la risposta inviato a un'altra domanda: Come marshall serie di struct in C #?

Quando il marshalling a quanto pare il valore predefinito è di maresciallo i parametri come in. In caso contrario, hanno bisogno di essere esplicitamente dichiarato o In, Out. Dopo aver specificato che in modo esplicito il mio codice dell'esempio ora funziona.

Grazie alla sua Skeetness per la risposta e per antonmarkov per l'esposizione ai MarshalAs.

private static extern int PassSomeStructs(int count, [In, Out] Box[] boxes, [In, Out] Spot[] points);

Altri suggerimenti

Da un MDSN articolo su array di smistamento: provare a impostare il seguente attributo sulle tue tipi di array. Questo è normalmente utilizzato per mettere in C # da C ++, ma può anche essere richiesto per ottenere valori aggiornati di nuovo in C #.

[DllImport(dll)]
private static extern int PassSomeStructs(int count, 
    [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] Box[] boxes, 
    [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] Spot[] points);

Si veda anche questo articolo per un esempio di successo a due vie di smistamento:

http: //social.msdn.microsoft.com/forums/en-US/csharplanguage/thread/ff0123d0-506b-4de2-bfb5-f690c9358826/

Avete provato ad aggiungere l'arbitro / out parola chiave per il vostro C # extern?

Un'altra idea è provare a passare in un IntPtr al posto della classe stessa, o passando in -AS- un IntPtr ...

Credo che le strutture vengono copiati, non passati per riferimento per impostazione predefinita.

Onestamente accoltellato nel buio, ma non ha ancora risposte, quindi speriamo che questo aiuta ...

Interop è ancora in "è magia" stage per me ...

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top