Klasse die ein Array mit anderer Klasse enthält mit C# an SPS senden

spsbeginnerin

Level-1
Beiträge
7
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo ich hatte das schonmal gestellt die Frage, aber weil noch niemand geantwortet hat, dachte ich, ich frag nochmal präziser und einfacher.

Ich möchte ein Objekt einer Klasse senden, welches einfache Attribute hat (short, bool etc.) und ein Array bestehend aus einer anderen Klasse. Also

[StructLayout(LayoutKind.Sequential, Pack = 0)]
class Class1{
short id;
short type;
[MarshalAs(UnmanagedType.I1)]
bool exist;
ComplexClass [] complex_array;
}

[StructLayout(LayoutKind.Sequential, Pack = 0)]
ComplexClass{
[MarshalAs(UnmanagedType.I1)]
bool b1;
short s1;
Position p1;
}

Wenn ich jetzt ein Objekt erstelle:
Class1 c1 = new Class1();

und das mit WriteAny(path, c1) an die sPS sende, dann funktioniert es leider nicht. id, type und exist wird richtig übertragen, aber im array stehen absurde werde drin. zb der erste Wert b1, wo ein bool stehen müsste steht: <Der Wert des Ausdrucks kann nicht gelesen werden.> und danach eine viel zu große zahl im short s1.

Funktioniert das einfach nicht ein Objekt mit writeany zu senden welches ein array von structs/class enthält? (bzw könnte es mit einem struct funktionieren?)
wie muss das mit dem MarshallAs angewendet werden? Muss da auch vor dem Attribut complex_array in class1 hingeschrieben werden wie es gemarshalled werden soll(müsste ja eigentlich reichen das ist der Definition der Klasse zu machen..

Auf der Beckhoff seite steht:
eise keine feste Länge haben, muss mit dem Property SizeConst die Grösse des Arrays bzw. des Strings festgelegt werden. Das Marshallen von Mehrdimensionale Arrays oder Arrays von Strukturen ist mit dem Marhaler des .NET Frameworks 1.1 nicht möglich. Mehrdimensionale Arrays müssten auf eindimensionale Arrays abgebildet werden. Arrays von Strukturen müssten in der .NET Struktur aufgelöst werden.

ich nutze ja ein höheres net-framework, aber vielleicht haben sie es einfach noch nicht behoben? weiß jemand irgendetwas dazu? Oder hat eine Alternative Lösung? Alle Attribute einzeln senden (funktioniert, sowohl für attribute als für das array) dauert halt ganz schön lange...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Naja ... normalerweise stellt man die Frage dann nicht ein 2. Mal sondern man ergänzt die ursprüngliche Frage mit weiteren Informationen / Beiträgen - dadurch poppt sie dann in der Fragenliste auch wieder nach oben ... aber sei es drum.

Mein Vorschlag dazu wäre :
Ich würde hier eventuell gar nicht herum-marshallen sondern mir in der Klasse eine Property (oder Funktion) erstellen, die die relevanten Einzel-Informationen in einem für die SPS verdaubarem Format (also z.B. als Array of Byte) aufbereitet. Genauso kannst du dann auch umgekehrt die gleiche Property (oder eine Methode) hernehmen um diese Array of Byte wieder in die Einzel-Bestandteile aufzubereiten (zu zerlegen).
Wobei das vorgeschlagene aus meiner Sicht eine Art "customized marshallen" wäre ...

Gruß
Larry
 
// Specifies how .NET should marshal the array
// SizeConst specifies the number of elements the array has.
[MarshalAs(UnmanagedType.ByValArray, SizeConst:=4)]
dintArr : Array[0..3] of Longint;also hier wird ja 4 angegeben, wenn das ein Array von einem komplexeren Datentyp ist, müsste das dann genauso sein? (zumindest funktioniert das bei mir leider nicht...obwohl es natürlich auch an etwas anderem problem liegen könnte.

wie soll ich das bei Write Any übergeben?
writeany(path,c1) wo soll dort noch der datentyp des arrays rein? das array alleine senden, also writeany(path_zu_array, complex_array) funktioniert ja ohne dass ich noch typ / Anzahl angebe (muss für Read auf jeden fall aber gemacht werden).
 
ich hab ja nochmal ne frage gestellt und dann hat niemand mehr geantwortet ;) aber hätte einfach dadrin natürlich nochmal fragen können, allerdings war das beispiel auch sehr komplex und etwas undurchsichtig gestellt;)

kann ich denn ein Array of Byte auf die SPS senden, wenn in der SPS sich structs befinden? ich habe es schon mit einem binary reader probiert und das hat leider auch schon bei einer ganz einfachen struktur nicht geklappt :(

also SPS - struct:

int i1;
bool b2;
int i2;

c#
short i1;
bool b2;
short i2;

dazu habe ich in c#:
AdsStream dataStream = new AdsStream(5);
BinaryWriter binWrite = new BinaryWriter(dataStream);
binWrite.Write(i1);
binWrite.Write(b2);
binWrite.Write(i2);
adsClient.Write(_handle, dataStream);

da wird der 2. int-wert (also in c# sind das dann ja shorts, weil c#shorts auf sps-ints abgebildet werde) bleibt 0. ich denke das liegt an dem bool davor...??
 
Zuviel Werbung?
-> Hier kostenlos registrieren
ein ADSStream besteht aus einer Anzahl Byte. Das Bool musst du dann wandeln.
kann ich denn ein Array of Byte auf die SPS senden, wenn in der SPS sich structs befinden?
Ja. Das Abbild muss allerdings gleich sein.
Vor dem beschreiben des Stream die Position auf 0 setzen:D

Bei deinem 1. Versuch muss Pack = 1 sein.
 
Zuletzt bearbeitet:
Hallo,
ich habe nochmal eine andere Frage gerade:

Wenn ich ein Array von Strings senden möchte, also ein string[] arr = new string[14]. wenn ich das nun senden möchte.
writeAnay(handler,arr) auf eine sps variable die auch 14 strings enthält. dann sagt mir C# dass ich folgendes verwenden soll:

Use overload WriteAny(uint indexGroup, uint indexOffset, object value, int characters)) for strings.

was genau sollen hier indexGroup und offset bedeuten? könnte mir jemand sagen, wie ich writeany für ein array von 14strings verwenden kann?
VG
 
Zurück
Oben