Problemaufgabe von Werten zu einer Struktur in C ++ an eine Struktur, die von C# übergeben wurde

StackOverflow https://stackoverflow.com/questions/1903173

Frage

Ich habe eine Funktion in C#, die ein Array von Strukturen in ein in C ++ geschriebener DLL übergibt. Die Struktur ist eine Gruppe von INTs und wenn ich die Daten in der DLL vorlesen, kommen alle Werte gut heraus. Wenn ich jedoch versuche, an die Elemente aus C ++ zu schreiben, werden die Werte nie angezeigt, wenn ich versuche zu lesen, dann wieder 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;
}
War es hilfreich?

Lösung 3

Ich fand die Antwort auf eine andere Frage: Wie kann man Strukturen in C#Marshall -Array von Strukturen haben?

Beim Marschessen wird der Standard die Parameter wie in anscheinend marschhal. Andernfalls müssen sie ausdrücklich als out oder in, draußen deklariert werden. Nach Angabe des expliziten My Code funktioniert das Beispiel jetzt.

Danke an seine Skeetness für die Antwort und zu Antonmarkov für die Exposition gegenüber den Marschallen.

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

Andere Tipps

Von einem MDSN -Artikel Bei Marshalling -Arrays: Versuchen Sie, das folgende Attribut auf Ihren Array -Typen festzulegen. Dies wird normalerweise zum Aufrufen von C# von C ++ verwendet, kann jedoch auch für die Erlangung aktualisierter Werte in C# erforderlich sein.

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

In diesem Artikel finden Sie auch ein Beispiel für ein erfolgreiches Zwei-Wege-Marshalling:

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

Haben Sie versucht, Ihr C# extern das REF/OUT -Keyword hinzuzufügen?

Eine andere Idee ist, zu versuchen, in ein INTPTR anstelle der Klasse selbst zu bestehen oder sie in einen Intptr zu geben ...

Ich glaube, dass Strukturen kopiert und standardmäßig nicht mit Referenz übergeben werden.

Ehrlich gesagt im Dunkeln, aber Sie haben noch keine Antworten, also hoffentlich hilft dies ...

Interop ist immer noch in der "Es ist magischen" Bühne für mich ...

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top