Forum: PC-Programmierung C#: Zugriff auf Strukturelemente verweigert


von csharp_user (Gast)


Lesenswert?

Guten Morgen,

in einer Klasse habe ich eine Struktur definiert.
1
        struct mac_address
2
        {
3
            byte byte1;
4
            byte byte2;
5
            byte byte3;
6
            byte byte4;
7
            byte byte5;
8
            byte byte6;
9
        };

Nun möchte ich in der Initialisierungsfunktion auf die Strukturelemente 
zugreifen.
1
public void btnInit_Click(object sender, System.EventArgs e)
2
{
3
  ...
4
  mac_address mac_src = new mac_address(); ;
5
  mac_src.byte1 = 0;
6
}

Leider wird der Zugriff verweigert. Folgende Fehlermeldung erscheint in 
Visual Studio 2010:

Fehler 1 Der Zugriff auf "netpcap.Form1.mac_address.byte1" ist aufgrund 
der Sicherheitsebene nicht möglich.

Wie kann man auf die Elemente von der Struktur zugreifen?

von Borislav B. (boris_b)


Lesenswert?

Mach die Member public.
Auf private Member kannst du von außen natürlich nicht zugreifen.

von csharp_user (Gast)


Lesenswert?

Hallo Boris,

danke für deine Unterstützung. Ich hab bereits alles auf prublic 
umgestellt. Die Fehlermeldung erscheint trotzdem.

von Peter II (Gast)


Lesenswert?

bei einer struct sind alle Member immer public.

kann es sein das die struct selber in ein Klasse nur private ist?

Zeige mal etwas mehr code.

von csharp_user (Gast)


Angehängte Dateien:

Lesenswert?

Siehe Methode
1
btnInit_Click
.

von Peter II (Gast)


Lesenswert?

csharp_user schrieb:
> Siehe MethodebtnInit_Click .

wenn ich das richtig sehen bist du ja nicht mehr in der klasse Form1.

public struct mac_address

von csharp_user (Gast)


Lesenswert?

Das kann ich nicht ganz nachvollziehen. Die Methode btnInit_Click wird 
doch in der Klasse Form1 definiert.

von Borislav B. (boris_b)


Lesenswert?

Peter II schrieb:
> bei einer struct sind alle Member immer public.

Sicher?

Zitat:
The access level for class members and struct members, including nested 
classes and structs, is private by default.

von Peter II (Gast)


Lesenswert?

csharp_user schrieb:
> Das kann ich nicht ganz nachvollziehen. Die Methode btnInit_Click wird
> doch in der Klasse Form1 definiert

ich habe keine richtigen Viewer parat.

davor kommt doch aber die main, die steht doch auch nicht in dem Form 
oder?

von csharp_user (Gast)


Lesenswert?

Ich hab die Struktur als public definiert. Die Fehlermeldung ist gleich.

von Peter II (Gast)


Lesenswert?

Boris P. schrieb:
> Sicher?
>
> Zitat:
> The access level for class members and struct members, including nested
> classes and structs, is private by default.

naja, bei C++ bin ich mir sicher, ich dache das es bei C# auch so ist

> In C++, a structure is the same as a class except that its members are
> public by default.

von csharp_user (Gast)


Lesenswert?

So. Und wie kann ich das Problem nun beheben. Es muss doch verdammt 
nochmal möglich sein. Dieses C# ist echt ein komplizierter Dreck!

von Peter II (Gast)


Lesenswert?

csharp_user schrieb:
> Dieses C# ist echt ein komplizierter Dreck!

C# ist eine saubere Sprache, wenn du damit nicht umgehen kannst liegt es 
bestimmt nicht an der Sprache.

hast du es mit dem Public der Members mal versucht? Wie hast du es 
getestet?

von csharp_user (Gast)


Lesenswert?

Hab ALLES in public umbenannt. Die Struktur ist ebenfalls public. Deie 
Fehlermeldung erscheint immer noch. Ich benötige C#, da ich Daten besser 
visualisieren kann. In C++ win32 ist dies nicht so möglich. Früher gab 
es noch das tolle Borland C/C++. Da war die GUI echt toll.

von Peter II (Gast)


Lesenswert?

csharp_user schrieb:
> Hab ALLES in public umbenannt. Die Struktur ist ebenfalls public.

bitte zeigen und ein screenshot der Fehlermeldung.

von csharp_user (Gast)


Angehängte Dateien:

Lesenswert?

Anbei der Screenshot.

von Peter II (Gast)


Lesenswert?

csharp_user schrieb:
> Anbei der Screenshot.

jetzt noch bitte den aktuellen code dazu.

von csharp_user (Gast)


Angehängte Dateien:

Lesenswert?

Code befindet sich im Anhang.

von Peter II (Gast)


Lesenswert?

csharp_user schrieb:
> Code befindet sich im Anhang.

und wo sind dort die member public?

von csharp_user (Gast)


Lesenswert?

Was für member?

von Peter II (Gast)


Lesenswert?

csharp_user schrieb:
> Was für member?

byte1 ist ein member der struct und diese muss public sein.

von csharp_user (Gast)


Lesenswert?

Achso! Ja ok. Jetzt geht es auch. Vielen vielen Dank.

von Borislav B. (boris_b)


Lesenswert?

Der Kreis schließt sich... ^^

von csharp_user (Gast)


Lesenswert?

Nochmals Danke.

Nun hab ich ein weiteres Problem.
Die Struktur ethernet_header möchte ich nun in ein frame kopieren.
1
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
2
        public struct ethernet_header
3
        {
4
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
5
            public byte[] dest;      
6
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
7
            public byte[] source;  
8
            public int type;  
9
        };

Dieses Frame ist folgendermaßen definiert:
1
        byte[] packet = new byte[65536];

Welche Möglichkeit gibt es in C#, um die Struktur in das Byte-Array 
packet zu kopieren?

von Borislav B. (boris_b)


Lesenswert?

Du könntest die Member mit einem BinaryWriter in einen Memory Stream 
schreiben.

von csharp_user (Gast)


Lesenswert?

In C geht dies viel eleganter. In C# ist das echt kompliziert.
Gibt es in C# eine Methode, mit der man eine Struktur in ein Byte-Array 
umwandeln kann?

von Lenny D. (le-do)


Lesenswert?

Stichwort Serialization, google:
c# serialize struct to byte array
die ersten 3 ergebnisse machen das alle gleich, kann also nich ganz 
falsch sein.

von Ben S. (theben)


Lesenswert?

Also ich arbeite mit Struct in C# überhaupt nicht ich vervende einfach 
eine Eigene Klasse dafür die Einfach nur Eigenschaften enthällt. Damit 
lässt sich viel leichter arbeiten

von Borislav B. (boris_b)


Lesenswert?

csharp_user schrieb:
> In C geht dies viel eleganter.

Eleganz liegt im Auge des Betrachters. Ich würde mal behaupten in C geht 
es an der Stelle eher "Quick & Dirty".

So etwa würde ich das vermutlich schreiben:
1
   class MyClass
2
    {
3
      public int Prop1 { get; set; }
4
      public byte Prop2 { get; set; }
5
6
      public byte[] ToByteArray()
7
      {
8
        var stream = new MemoryStream();
9
        using (var writer = new BinaryWriter(stream))
10
        {
11
          writer.Write(Prop1);
12
          writer.Write(Prop2);
13
        }
14
        return stream.ToArray();
15
      }
16
    }

: Bearbeitet durch User
von csharp_user (Gast)


Lesenswert?

Mit serialize funktioniert es auch nicht. Visual Studio gibt eine 
Fehlermeldung aus:

SerializationException wurde nicht behandelt.
Der Typ "netpcap.Form1+ethernet_header" in Assembly "netpcap, 
Version=1.0.5449.24838, Culture=neutral, PublicKeyToken=null" ist nicht 
als serialisierbar gekennzeichnet.
1
            BinaryFormatter formatter = new BinaryFormatter();
2
            MemoryStream stream = new MemoryStream();
3
            formatter.Serialize(stream, ehdr);
4
            Byte[] buffer = stream.ToArray();

von Borislav B. (boris_b)


Lesenswert?

csharp_user schrieb:
> ist nicht
> als serialisierbar gekennzeichnet.

Hast du sie denn als serialisierbar gekennzeichnet (per entsprechendem 
Attribut)?

von Peter II (Gast)


Lesenswert?

csharp_user schrieb:
> Mit serialize funktioniert es auch nicht. Visual Studio gibt eine
> Fehlermeldung aus:

hast du auch mal die Fehlermeldung gelesen?

Du musst sie als "serialisierbar gekennzeichnet"

Übrigens bekommt du im netzt auch mehr Hilfe, wenn man sich keine 
deutschen Fehlermeldungen anzeigen lässt.

von csharp_user (Gast)


Lesenswert?

Ok. Die beiden Strukturen habe ich nun mit [Serializable] serialisierbar 
gemacht. Zumindest erscheint keine Fehlermeldung mehr. Allerdings, wenn 
man sich den Puffer anschaut werden die Daten nicht von Anfang an in den 
Puffer "buffer" kopiert.

von Peter II (Gast)


Lesenswert?

csharp_user schrieb:
> Allerdings, wenn
> man sich den Puffer anschaut werden die Daten nicht von Anfang an in den
> Puffer "buffer" kopiert.

Ich vermute mal das diese Art der Serialisierung nicht dafür gedacht 
ist, da werden noch Infos zu Klasse mit übertragen, damit man am anderen 
Ende das objekt wieder herstellen kann.

Wenn es nicht gerade im Geschwindigkeit geht, warum nicht einfach in 
einer schleife es in das neue Array kopieren?

C# ist nun mal nicht dafür gedacht, LowLevel Packete zusammenzubauen.

von Peter II (Gast)


Lesenswert?


von Lenny D. (le-do)


Lesenswert?

OK sry hab dich mit dem Stichwort vielleicht auf die falsche Fährte 
gelockt, was ich eigentlich meinte ist (wenn man genau meine Wörter in 
Google eingibt) diesen Link (und ähnliche):
http://wingerlang.blogspot.de/2011/11/c-struct-to-byte-array-and-back.html

Das benutzt nicht die .net Serialization sonder sieht mir sehr nach 
einer C-typisch nachgebildeten Pointerarithmetik aus:
http://msdn.microsoft.com/de-de/library/2zhzfk83%28v=vs.110%29.aspx

von nicht"Gast" (Gast)


Lesenswert?

Moin,

also von meiner Seite aus kann ich nur sagen. Immer wenn ich so was 
schreiben will, schreit es mich regelrecht an, dass ich das lieber in 
einem Array speichern soll.

statt:
1
  struct mac_address
2
        {
3
            byte byte1;
4
            byte byte2;
5
            byte byte3;
6
            byte byte4;
7
            byte byte5;
8
            byte byte6;
9
        };

viel lieber
1
byte []mac_address = new byte[6];

Das macht die Verarbeitung viel einfacher.

Grüße,

von Ich (Gast)


Lesenswert?

Versuchs mal so:
byte[] StructureToByteArray(object obj)
        {
            int len = Marshal.SizeOf(obj);
            byte[] arr = new byte[len];
            IntPtr ptr = Marshal.AllocHGlobal(len);
            Marshal.StructureToPtr(obj, ptr, true);
            Marshal.Copy(ptr, arr, 0, len);
            Marshal.FreeHGlobal(ptr);
            return arr;
        }

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.