wp_xyz hat geschrieben:Schön zu wissen. Aber ehrlich gesagt - vor solchem Code halte ich Abstand, da verkommt die schön leserliche Programmiersprache Pascal zur Geheimschrift a la C & Konsorten.
Naja ich finde es deutlich übersichtlicher als Pointerarithmetik. Man muss nunmal das verhalten von SetLength kennen (zum einen finde ich das verhalten weder unerwartet, noch dazu finde ich sollte man erwarten können das Pascalprogrammierer wenigstens die grundlegenden System Funktionen kennen sollten, und falls nicht, steht es in der Doc), oder einen Kommentar drüber schreiben. Das tolle an SetLength ist auch, wenn es nichts kopieren muss, kopiert es auch nichts. Und wenn man eine Zeile sowas wie "ensures a unique copy" als Kommentar drüber schreibt, kann jeder mit einem blick sehen was passiert. Bis man die Pointerschleife verstanden hat braucht man da länger
Helios hat geschrieben:Hallo Gentlemen,
vielen Dank für Euren super Support am Sonntag Abend!
Hier noch der Ausschnitt aus meinem Source welches ich mit Eurer Hilfe erstellen konnte
(wobei ich das zusätzlich schöne inc() von wp_xyz als Ersatz für meine aufwändigere (Index) Multiplikation gerne verwenden/übernehmen werde.
Wieder was gelernt!:-)
type
...
ASAM_MCD2_Text_TableFuncParam = packed record // type 11
Value1: double;
ByteArray: array [0..31] of byte;
end;
...
PASAM_MCD2_Text_TableFuncParam = ^ASAM_MCD2_Text_TableFuncParam;
TFunc = class
public
...
TableValues: array of ASAM_MCD2_Text_TableFuncParam;
...
end;
constructor TFunc.Create(param: array of byte; size: word);
var
i: word;
begin
SetLength(TableValues, size);
for i := low(TableValues) to high(TableValues) do
TableValues[i] := PASAM_MCD2_Text_TableFuncParam(@param[i*SizeOf(ASAM_MCD2_Text_TableFuncParam)])^;
end;
Nochmals Danke!
Falls jemand noch eine Lösung hat, bei dem gar keine Iteration über die TableValues[i]
(und kein Aufruf von SetLength?) notwendig ist (evtl. der Ansatz von Warf?)
Wäre ich daran auch sehr interessiert, aber schon so ist das schon deutlich schöner als das was ich vorher
zusammenprogramiert habe.
Gute Nacht und Euch allen einen schönen Start in die Woche!
Gruß
Arne
Verwende doch Move, genau dafür existiert die Funktion doch:
Code: Alles auswählen
SetLength(TableArray, Length(ByteArray) div SizeOf(ASAM_MCD2_Text_TableFuncParam));
Move(ByteArray[0], TableArray[0], Length(ByteArray);
Ist zwar etwas länger als SetLength, aber immer noch deutlich kürzer als dein Code und deutlich übersichtlicher.
Aber was genau hält dich davon ab einfach den Array zu Casten, also ohne setlength? Ist es wirklich notwenig den Array zu Kopieren? Immerhin kostet das super viel Zeit im Gegensatz zum Pointer Cast.
Außerdem statt constructor TFunc.Create(param: array of byte; size: word); verwende am besten 1. TBytes statt array of byte, denn array of byte in Funktionsparametern ist ein offenes Array, kein dynamisches (was zu unerwarteten Problemen führen kann). Wenn man mit Arrays arbeitet, mehr als nur einmal eben in einer Funktion, lohnt es sich fast immer dafür einen eigenen Typen zu definieren, so umgehst du das open Array Problem. Für Bytes (TBytes), strings (TStringArray und viele mehr gibt es das auch schon vordefiniert 2. warum word als size? bist du wirklich sicher das die Anzahl an bytes kleiner 65000 ist? und selbst wenn ist deine CPU auf IntPtr deutlich schneller als auf 16 bit words (außer du hast einen Rechner aus den 80ern mit ner 16 bit CPU, dann ist UIntPTr = Word )