Forum: PC-Programmierung Doppelzeiger in C#


von FuchsS (Gast)


Lesenswert?

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.

von Arc N. (arc)


Lesenswert?

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.

von Peter (Gast)


Lesenswert?

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)

von entity (Gast)


Lesenswert?

das geht schon:

 byte[,] Data_out = new byte[32, 32];

von Peter (Gast)


Lesenswert?

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.

von FuchsS (Gast)


Lesenswert?

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

von Markus V. (valvestino)


Lesenswert?

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

von Markus V. (valvestino)


Lesenswert?

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
Noch kein Account? Hier anmelden.