Hi, wie der Betreff schon sagt möchte in C# gerne einen Zeiger auf ein zweidimensionales Array erzeugen. Ich habe eine dll Datei deren Funktionen ich in C# verwenden möchte, soweit funktioniert das auch schon. Jedoch gibt es eine Funktion die einen Doppelzeiger auf ein zweidimensionales Array erwartet. Das zweidimensionale Array habe ich wie folgt erstellt: byte[][] Data_out = { new byte[32] }; Nun möchte ich einen Zeiger darauf erstellen. Ungefähr so: fixed (byte** test = Data_out) // Funktioniert allerdings nicht So funktioniert es nur mit Zeigern auf eindimensionale Arrays. Hat jemand eine Idee wie man solche Zeiger in C# erstellt. Einen guten Rutsch schon mal an alle.
Günstig wäre zu wissen, wie die Funktion in der DLL deklariert ist bzw. was die Funktion damit macht (liefert sie ein neues Array zurück etc?). MarshalAsAttribute, eine Methode aus System.Runtime.InteropServices.Marshal oder IntPtr sollten eigentlich reichen.
FuchsS schrieb: > Das zweidimensionale Array habe ich wie folgt erstellt: > byte[][] Data_out = { > new byte[32] > }; ich glaube nicht das es so geht, weil es .net das ganze anders ablegt als C. Du müsssten das ganze vermutich als 1Dimensonales Array ablegen. (ein zwei Dimensionales mit konstanter größe ist eh nichts anders)
entity schrieb: > byte[,] Data_out = new byte[32, 32]; klar kann man es so anlegen, aber ich bin mir nicht sicher wie die Daten im Speicher angeordnet sind. Data_out ist ein .NET ein Object mit eigenschaften ( z.b. anzahl der elemente) und das heist es müssen irgendwo noch objektdaten existieren die zusätzlich zu den Nutzdaten vorhanden sind. Und das ist das Problem, in C gibt es sotwas nicht.
Arc Net schrieb: > Günstig wäre zu wissen, wie die Funktion in der DLL deklariert ist bzw. > was die Funktion damit macht (liefert sie ein neues Array zurück etc?). Ja in der dll wird das array ausgelesen und danach neu beschrieben Peter schrieb: > klar kann man es so anlegen, aber ich bin mir nicht sicher wie die Daten > im Speicher angeordnet sind. Data_out ist ein .NET ein Object mit > eigenschaften ( z.b. anzahl der elemente) und das heist es müssen > irgendwo noch objektdaten existieren die zusätzlich zu den Nutzdaten > vorhanden sind. Und das ist das Problem, in C gibt es sotwas nicht. also kann das array nicht wie in c verwendet werden. Dann muss ich mir wohl was anderes einfallen lassen wie ich die daten am geschicktesten austausche. Danke für die hilfe
Peter schrieb: > entity schrieb: >> byte[,] Data_out = new byte[32, 32]; > > klar kann man es so anlegen, aber ich bin mir nicht sicher wie die Daten > im Speicher angeordnet sind. Data_out ist ein .NET ein Object mit > eigenschaften ( z.b. anzahl der elemente) und das heist es müssen > irgendwo noch objektdaten existieren die zusätzlich zu den Nutzdaten > vorhanden sind. Und das ist das Problem, in C gibt es sotwas nicht. Es ist doch (fast) völlig unerheblich, wie .net die Objekte ablegt. Wichtig ist, dass die unmanaged-Funktion in der Dll die Daten im richtigen Format erhält. Dafür ist P/Invoke mit seinen Marshalling-Funktionen da. Das führt die entsprechenden Konvertierungen durch. FuchsS schrieb: > Ich habe eine dll Datei deren Funktionen ich in C# verwenden möchte, > soweit funktioniert das auch schon. Jedoch gibt es eine Funktion die > einen Doppelzeiger auf ein zweidimensionales Array erwartet. Mir scheint, Du siehst vor lauter Bäumen (Doppelzeiger) nicht den Wald (was macht die Funktion). Einen Doppelzeiger verwendet man in C bei den Funktionsparametern z.B. dann, wenn in der Funktion ein Speicherbereich neu allokiert werden soll (Ich entschuldige mich bereits an dieser Stelle für meine ggf. unpräzise Formulierung aus sicht eines C-Gurus, meine Kenntnisse sind seit über 10 Jahren etwas eingerostet). Anders formuliert: Die Funktion soll einen Zeiger auf einen Speicherbereich ändern und aus irgend welchen Gründen wird dafür nicht der Funktions-Rückgabewert sondern ein Funktionsparameter verwendet. Für sowas gibt es in C# "out" und "ref":
1 | [DllImport...] |
2 | private static int MyUnmanagedFunction( out byte[] pointerPointer ); |
Die andere Frage ist natürlich, wie das zweidimensionale Array organisiert ist, das aus der Funktion herauskommt. Ich würde ggf. in C# ein eindimensionales Array verwenden und dessen Inhalt dann in ein passendes zweidimensionales C#-Array umkopieren (sofern es sich nicht um Datenmengen im Gigabyte-Bereich handelt). Was auch noch zu prüfen wäre: Die Speicherverwaltung. Du hast hier einen Übergang zwischen unmanaged und managed C#. Wenn die Dll-Funktionen erwarten, dass der allokierte Speicher ausserhalb freigegeben wird (ist das zwar ziemlicher Müll), Du musst es aber dann irgendwie selbst handeln. Gruß Markus
Ich habe natürlich noch eine Kleinigkeit vergessen. Unter http://www.codeproject.com/ findest Du mit der Suche nach P/Invoke eine paar Artikel zum Thema, auch mit Informationen zum Marshalling. Allerdings ist das eine englische Web-Site. Markus
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.