![]() |
Pointer in C#
Hi,
Im Moment siehts so aus, dass ich übers Netzwerk Daten geschickt bekomme. Die Socketklasse von C# (bzw dem .NET Framework) macht das ja alles über Byte-Arrays. Soweit ja in Ordnung. Allerdings will ich jetzt dieses Byte Array in ein struct kopieren, bzw das Array so interpretieren können. Das ganze ist allerdings scheinbar nicht so einfach -.- Ich habe keinen Move befehl o.ä. gefunden mit dem ich die Bytes einfach verschieben/kopieren kann und ein Pointer des structtyps auf dieses Array funktioniert auch nicht. Also mein Quelltext (= Müll) sieht so aus:
Code:
*)
public struct TPlayerState
{ public UInt16 id; public int x; public int y; public UInt32 color; } // ... byte[] buff = new byte[14]; // Daten in buff lesen TPlayerState* x = (TPlayerState*)(byte*)buff[0]; //<---- * // ... Zitat:
Also
Code:
=
Typ* x;
Delphi-Quellcode:
var x: ^Typ;
Code:
=
x = *var;
Delphi-Quellcode:
Stimmt das soweit? Und wie dereferenziert man in C#? Und was soll wie gesagt oben diese Meldung? -.-
x := @var;
In Delphi ist das alles unkomplizierter..... |
Re: Pointer in C#
C# ist managed code. Da gibt es keine Pointer. Dafür gibt es native Sprachen, wie Delphi oder C.
|
Re: Pointer in C#
Zitat:
|
Re: Pointer in C#
Unsafe Code würde ich in .NET versuchen zu vermeiden. Es geht praktisch immer ohne. Die Frage ist hier, ob du Einfluss auf das sendende Programm hast. Wenn ja, kannst du einfach auf beiden Seiten einen Standard-Serialisierungsmechanismus verwenden (in Java gibt es so etwas, mich würde es wundern, wenn das in .NET fehlte). Andernfalls kannst du die Daten manuell aus dem Byte-Array herausziehen. Ich bin mir ziemlich sicher, dass es noch einen direkten Weg gibt (es gibt schließlich sogar Attribute für die Struct-Ausrichtung), aber er fällt mir gerade nicht ein.
|
Re: Pointer in C#
Hi,
Also letztendlich ist es mir egal, wie ich die Bytes in das struct Ding bekomme -.- Hab Einfluss auf das Sendende Programm. Es ist ein Client, den ich in Delphi schreibe. Was ist ein Standard-Serialisierungsmechanismus? Klar könnte ich das ganze manuell ausm Array rausziehn, aber das ist doch viel zu umständlich und wenn mein Server mal viel zu tun hat, dann ist das doch unnötige Arbeit... |
Re: Pointer in C#
Aua!
.NET ist eine managed Runtime. Da hat man nicht mit Pointern zu arbeiten. Punkt. Dadurch, dass der Speicher von der Runtime verwaltet wird, hast Du nahezu gar keine Kontrolle darüber, wie ein Struct im Speicher aussieht. Das kann sich sogar je nach dem von einem Start der Applikation zum nächsten ändern. Anzunehmen, dass ein Struct ein bestimmtes Layout im Speicher hätte, ist in .NET grundlegend falsch (Insbesondere, wenn Du in C# einfach nur 'int' nimmst. Int ist nämlich zur Zeit ein Int32, kann aber ggf. auf 64bit Systemen je nach Optimierung auch auf einen Int64 mappen). Ausnahme: Du forcierst das über Attribute, aber das unterbindet dann zwangsläufig die Optimierung und kann hintenraus ordentlich performance kosten. Du kannst den Code möglicherweise als unsafe deklarieren, aber damit kommst Du dann spätestens bei der CAS (Code Access Security) Probleme. Schau Dir mal den Namespace System.Runtime.Serialization bzw. System.Runtime.Serialization.Formatters an. Da hats nen BinaryFormatter. Ich denke, das wäre der bessere Ansatz um Dein Struct aus dem empfangenen Stream zu füllen. |
Re: Pointer in C#
Und falls du doch darauf bestehst:
Code:
Aber Phoenix hat schon Recht. Wenn du die korrekten Serialization-Interfaces implementierst, kannst du das wunderbar ohne rumgepointere machen. Dazu gibt's im MSDN unter den entsprechenden Topics auch viele Beispiele ;)
[StructLayout(LayoutKind.Sequential)]
public struct TPlayerState { public UInt16 id; public int x; public int y; public UInt32 color; } // unsafe void MeineMethode // ... byte[] buff = new byte[14]; fixed(byte* xb = &(buff[0])) { TPlayerState* x = (TPlayerState*)xb; } // ... |
Re: Pointer in C#
Mh...
Ohne Pointer ist doof. :stupid: Mal so nebenbei... Oder sollte man einen Server, der auch auf Linux laufen soll vielleicht doch eher mit C++ schreiben? Wenn ich mir das hier so durchlese zweifel ich langsam daran, dass C# die richtige Sprache ist... |
Re: Pointer in C#
Zitat:
![]() |
Re: Pointer in C#
Die Klassen aus System.Runtime.Serialization sind genau das, was ich mit einem Standard-Serialisierungsmechanismus meinte. Eine nicht-native Sprache benötigt schließlich auch irgendeinen Mechanismus, Objektinstanzen zu speichern, ohne dabei gleich unsafe zu werden. Bezüglich des direkten Wegs habe ich mich übrigens getäuscht. Das war eben jene Geschichte mit dem StructLayout-Attribut, und das verwendet man nur in Zusammenhang mit unsafe oder unmanaged Code.
|
Re: Pointer in C#
Zitat:
|
Re: Pointer in C#
Zitat:
|
Re: Pointer in C#
Köntest du den Playerstate nicht einfach als Text übertragen? also z.B. dezimal mit Leerzeichen getrennt:
1273 -73674 25062 -7246284 Das kan man dann einfach trennen und einzeln zuweisen - oder kommt es sehr auf Geschwindigkeit an? Edit: Alternativ kannst du ja auch sowas machen: id = arr[0] + arr[1] << 8; x = arr[2] + arr[3] << 8 + ... Ein kleines bisschen Schreibarbeit, aber schneller als Strings ;) |
Re: Pointer in C#
Zitat:
Zurzeit bin ich mir C++ am anschauen. Ich kann mich nicht so richtig mit diesen Frameworks anfreunden :? Werde dann wohl entscheiden ob ich C++ oder C# nehme. Was ist denn objektiv gesehen geeigneter? |
Re: Pointer in C#
Zitat:
Wenn Du mit C# nicht so gut zurecht kommst schau Dir mal Prism an :zwinker: Aber ich denke, in .NET bist Du für so einen Server sehr gut aufgehoben. Und wenn Du im Prinzip vorne 'nur' Sockets und hinten z.B. eine Datenbank hast, dann läuft das ganze auf Mono auch ohne weiteres. Du kannst ja z.B. auch mit C# auf Windows direkt gegen Mono anstelle des .NET Frameworks von Microsoft entwickeln und testen. Dann läufts auch unter Linux *g* |
Re: Pointer in C#
Hi,
Also ich komme mit C# soweit eigentlich bisher ganz gut zurecht aber ich muss die Sache mit den Pointern wohl erstmal verdauen, weil... Wie soll ich nur ohne meine lieben Pointer programmieren? :cry: :mrgreen: Naja ich werd mich wohl nochn bisschen mit C# und dem .NET auseinandersetzen müssen... Ich kann aber den Server auch erstmal "ganz normal" in C# (SharpDevelop) programmieren und dann später einfach mit Mono kompilieren oder muss ich dann alles umbauen? |
Re: Pointer in C#
Zitat:
|
Re: Pointer in C#
Zitat:
Das Compilieren zur IL ist noch plattformunabhängig und das JIT-Compiling wird ja transparent auf der Zielmaschiene durchgeführt ... |
Re: Pointer in C#
Was spricht eigentlich dagegen, die Daten in einen Stream zu schmeissen und dann Stück für Stück auszulesen? Da benötigt man doch keinen unmanaged code, Pointer o.ä... :gruebel:
|
Re: Pointer in C#
Zitat:
|
Re: Pointer in C#
Hi,
Habs jetzt so probiert:
Code:
*) Ausnahme System.Runtime.Serialization.SerializationExceptio n wurde im ausgeführten Programm ausgelöst:
[Serializable]
public struct TPlayerState { public UInt16 id; public int x; public int y; public UInt32 color; } public static void RecClientData(object client) { Socket csock = client as Socket; BinaryFormatter binf = new BinaryFormatter(); byte[] buff = new byte[14]; // Größere Pakete kommen zurzeit eh nicht an, von daher hab ichs mal so fest drin. int len; while ((len = csock.Receive(buff,SocketFlags.None)) > 0) { Stream ms = new MemoryStream(); ms.Write(buff,0,buff.Length); ms.Position = 0; switch (buff[0]) { case 0: Console.WriteLine("..."); break; case 1: TPlayerState ps = (TPlayerState)binf.Deserialize(ms); // <---- *) Console.WriteLine(ps.y); break; default:break; } // .... Das Streamende wurde erreicht, bevor die Verarbeitung abgeschlossen wurde. Kann mir da jemand sagen was ich falsch mache? Versenden tu ich das ganze so:
Delphi-Quellcode:
Gruß
type
TPlayerState = packed record id: Word; // 1 x,y: Integer; color: TColor; end; var data: TPlayerState; begin data.id := 1; data.x := 20; data.y := 40; data.color := clred; Client.Send(@data,SizeOf(TPlayerState)); end; Neutral General |
Re: Pointer in C#
Du musst natürlich auch zum Serialisieren den BinaryFormatter verwenden.
|
Re: Pointer in C#
Zitat:
Ich versende doch die Daten von einem Delphi Win32 Programm aus. Da hab ich keinen Binary-Formatter.... |
Re: Pointer in C#
Dann musst du entweder den unmanaged Weg gehen oder den Stream manuell parsen. Letzteres ist doch wirklich kein Problem.
|
Re: Pointer in C#
Schau Dir
![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:53 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz