Komplexes struct Marshallen
-
Hallo,
nach einigen Tagen Googlen und rumprobieren, muss ich mich nun doch an euch wenden. Ich hoffe ihr könnt mir weiter helfen.
Situation:
Aus einem C#-Programm soll eine Funktion einer C-Dll aufgerufen werden. Diese Funktion erwartet als Parameter ein 2-dimensionales Array einer simplen Struktur, außerdem ein Array von einer komplexeren Struktur (mit Array auf andere Struktur). Als Code sieht das vereinfacht so aus://Strukturen typedef struct { double x; double y; } coordpt; typedef struct { int type; char *data; } shapes; typedef struct { coordpt* points; int number; // Anzahl der Punkte } surface; //Funktion EXIMPORT eineFunction(coordpt** polygone,int* anz_points_in_poly, int anz_poly,shapes* shapeArray, int anz_shapes)
Dabei ist 'anz_points_in_poly' ein int-Array welches der Funktion anzeigt wieviele Elemente in den Array in Polygone sind, also aus wievielten Polygonen das erste, zweite... Polygon besteht.
In der Struktur shapes steht type für die Art des Pointers der übergeben wird, also ist data kein Char Array, sondern ein Pointer auf eine andere Struktur(z.b. surface) die in jeder Instanz der Struktur von einem anderem Typen sein kann.
Meine Versuche die Funktion aufzurufen, scheitern leider am Marshalling, ich habe eine Klasse folgendermaßen implementiert (ebenfalls vereinfacht):
class WrapperClass{ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct coordpt { public double x; public double y; } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct surface { public int type; public IntPtr data; } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct shape { public coordpt[] points; public int number; } [DllImport("EineDLL.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl)] public static unsafe extern int eineFunction(coordpt** polygone,int* anz_points_in_poly, int anz_poly,shapes* shapeArray, int anz_shapes); }
Meine Frage ist nun, wie bekomme ich meine Daten korrekt in die Funktion gemarshaled?
Leider habe ich keinen zugriff auf den Quellcode der Dll, ich habe mir deshalb auch eine eigene geschrieben mit ähnlichen Parametern, um zuschauen was auf der anderen Seite ankommt. Leider hab ich es mit den Funktionen der Marstall und GCHandler Methode nicht hinbekommen, die Funktion korrekt aufzurufen.
Ich hoffe jmd. hat schon einmal Erfahrung damit gemacht und kann mir eine Vorgehensweise beschreiben.
Danke im Voraus.
Gruß,
Nils
-
Ist das Problem noch vorhanden? Wenn dem so ist und keiner vorher eine Lösung hat, schaue ich es mir dieses Wochenende kurz an. Sowas in der Art habe ich schon gemacht und sollte daher machbar sein
Grüssli
-
Hi,
ich habe es jetzt so gelöst, dass ich alle Strukturen die Übergeben werden in Klassen "übersetzt" habe, die machen dann die Speicherveraltung über Marshal.Alloc(). Funktioniert eig. soweit gas gut...Danke, trotzdem
-
Vielleicht kannst du deine Loesung hier praesentieren, das nachfolgende Personen mit diesem Problem auch die Loesung bekommen. Ausserdem interessiert mich es auch