memcpy, gibts nicht, ? [ gelöst ]

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1498
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

memcpy, gibts nicht, ? [ gelöst ]

Beitrag von corpsman »

Guten Morgen Allerseit,

Ich hab hier 2 Pointer, welche beide auf gleich großen mittels getmem allokierten Speicher zeigen.

Nun will ich den Inhalt von a nach b Kopieren.

Laut Google solls da den Befehl

memcpy geben, den kennt mein Lazarus FPC 2.4.0 aber nicht.

Ich hab es mit Move Probiert, aber das scheint auch nicht zu gehen

In Welcher Unit soll ich denn nun das Memcpy finden , ?

Oder macht man das komplett anders ?

Was ich bisher gemacht habe :

Code: Alles auswählen

var p, p2:Pointer;
Begin
  p := getmem(Size);
  p2 := getmem(Size);
 
Schreibe an Speicheraddresse von P
 
  move(p,p2,size); // das scheint allerdings nur den Pointer p2 auf p um zu biegen und keine Kopie des Speicherbereiches an zu legen.
//  memcpy(p,p2,size); // gibt es wohl nicht
 
Arbeite mit p2 weiter
..
Zuletzt geändert von corpsman am Mo 8. Feb 2010, 10:52, insgesamt 1-mal geändert.
--
Just try it

Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1498
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: memcpy, gibts nicht, ?

Beitrag von corpsman »

Also ich hab das nun mittels :


Code: Alles auswählen

Procedure memcpy(Const source: Pointer; dest: Pointer; size: Integer);
Var
  i: Integer;
  b, b2: PByte;
Begin
  b := Source;
  b2 := dest;
  For i := 0 To Size - 1 Do Begin
    b2^ := b^;
    inc(b);
    inc(b2);
  End;
End;


Nachgebildet, und das geht auch, nur glaube ich irgendwie das es da was "eleganteres" gibt.
--
Just try it

Benutzeravatar
theo
Beiträge: 10500
Registriert: Mo 11. Sep 2006, 19:01

Re: memcpy, gibts nicht, ?

Beitrag von theo »

corpsman hat geschrieben: 
move(p,p2,size); // das scheint allerdings nur den Pointer p2 auf p um zu biegen und keine Kopie des Speicherbereiches an zu legen.


Das ist ja auch das, was du ihm damit befiehlst.
Die Daten liegen in p^, p2^

Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1498
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: memcpy, gibts nicht, ?

Beitrag von corpsman »

ja ich hatte ein C tutorial zu move gelesen, und da stand das es das selbe macht wie copy, na egal

Ich hab ja nun die Funktionierende Variante :

Code: Alles auswählen

Procedure memcpy(Const source: Pointer; dest: Pointer; size: Integer);
Var
  i: Integer;
  b, b2: PByte;
Begin
  b := Source;
  b2 := dest;
  For i := 0 To Size - 1 Do Begin
    b2^ := b^;
    inc(b);
    inc(b2);
  End;
End;


Die Frage ist nur, kann man das irgendwie "Eleganter" machen.

Die Pointer Zeigen übrigens momentan auf einen

Code: Alles auswählen

(* Die Reihenfolge ist hier Besonders WICHTIG*)
  TExternPartikel = Packed Record
    ID: Integer;
    PosX: Single;
    PosY: Single;
    PosZ: Single;
    DirX: Single;
    DirY: Single;
    DirZ: Single;
    Size: Single;
  End;


Später zeigen sie allerdings auf ein beliebig langes Byte array, das ich von einer C Library bekomme, deswegen mus ich also auf jedenfall in Byte schritten auflösen ...
--
Just try it

Benutzeravatar
theo
Beiträge: 10500
Registriert: Mo 11. Sep 2006, 19:01

Re: memcpy, gibts nicht, ?

Beitrag von theo »

corpsman hat geschrieben:Später zeigen sie allerdings auf ein beliebig langes Byte array, das ich von einer C Library bekomme, deswegen mus ich also auf jedenfall in Byte schritten auflösen ...


Kapier ich nicht. Dafür hast du ja den size Parameter.

Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1498
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: memcpy, gibts nicht, ?

Beitrag von corpsman »

RESET;

Ich habe die Procedure :

Code: Alles auswählen

Procedure memcpy(Const source: Pointer; dest: Pointer; size: Integer);
    Var
      i: Integer;
      b, b2: PByte;
    Begin
      b := Source;
      b2 := dest;
      For i := 0 To Size - 1 Do Begin
        b2^ := b^;
        inc(b);
        inc(b2);
      End;
    End;

geschrieben, diese kopiert eine Anzahl bytes ( size ) von Source nach dest, diese Anzahl kann auch z.b. 5 sein( da ich sie nicht kenne ist der Parameter ja da, Im Speziellen mus dieser aber eben keine Word allign grenzen treffen).

Nun bin ich der Meinung, dass das was ich da oben gebastelt habe, bei weitem nicht das ist was man als "Schnell" oder "Optimal" betiteln würde.

Meine Hoffnung ist nun das irgend ein ganz netter Mensch hier im Forum weis wie man die Prozedur memcpy anders implementieren kann, so das sie das selbe macht wie die hier gepostete Version nur eben viel schneller.
--
Just try it

Benutzeravatar
theo
Beiträge: 10500
Registriert: Mo 11. Sep 2006, 19:01

Re: memcpy, gibts nicht, ?

Beitrag von theo »

Aber warum verwendest du nicht move? (Ich meinte den size parameter bei move)

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: memcpy, gibts nicht, ?

Beitrag von mschnell »

corpsman hat geschrieben:ja ich hatte ein C tutorial zu move gelesen....

C Tutorial zum Delphi / FPC "move" ???? das nützt nix.

Korrekt ist natürlich move(a^, b^, size). (move benutzt var und const parameter)

Delphi-Codes für memcpy: Vorsicht bei überlappenden Quell und Zielbereichen !!! move kopiert automatisch so, als würde erst die Quelle zwischengespeichert und dann auf das Ziel kopiert. Das ist fast immer so gewünscht. Lineares vorwärts-kopieren macht unter Umständen etwas anderes.

-Michael

Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1498
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: memcpy, gibts nicht, ?

Beitrag von corpsman »

lol, jetzt hab ichs kapiert.

Also move macht genau was ich will, nur das ich halt vergessen hatte die ^ dahinter zu schreiben, danke für das deutlich machen.
--
Just try it

Mathias
Beiträge: 6209
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: memcpy, gibts nicht, ? [ gelöst ]

Beitrag von Mathias »

Re: memcpy, gibts nicht, ?
Ich stand auch gerade mit move() an, als ich ein C-Programm übernehmen wollte.
Ich habe es jetzt so gelöst, und es funktionier bestens.

Code: Alles auswählen

procedure memcpy(dest, src: Pointer; size: SizeInt); cdecl; external 'c';

Code: Alles auswählen

type
    TUBORec = record
      scale: TGLfloat;
      translation: TVector3f;
      rotation: TVector4f;
      Enabled: TGLboolean;
    end;

const
  UBORec: TUBORec = (
    scale: 0.5;
    translation: (0.1, 0.1, 0.0);
    rotation: (90, 0, 0, 1);
    Enabled: True);

var
  buffer: Pointer;
begin
  memcpy(buffer, @UBORec.translation, 48);
  memcpy(buffer + 12, @UBORec.scale, 4);
  //  move(@UBORec.scale, buffer+12, 4)
Move() steht schon beim +12 an.
Mit Move() bin ich immer am üben, bis es endlich mal klappt,
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

PascalDragon
Beiträge: 834
Registriert: Mi 3. Jun 2020, 07:18
OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
CPU-Target: Aarch64 bis Z80 ;)
Wohnort: München

Re: memcpy, gibts nicht, ? [ gelöst ]

Beitrag von PascalDragon »

Mathias hat geschrieben:
So 17. Sep 2023, 17:36
Re: memcpy, gibts nicht, ?
Ich stand auch gerade mit move() an, als ich ein C-Programm übernehmen wollte.
Ich habe es jetzt so gelöst, und es funktionier bestens.

Code: Alles auswählen

procedure memcpy(dest, src: Pointer; size: SizeInt); cdecl; external 'c';

Code: Alles auswählen

type
    TUBORec = record
      scale: TGLfloat;
      translation: TVector3f;
      rotation: TVector4f;
      Enabled: TGLboolean;
    end;

const
  UBORec: TUBORec = (
    scale: 0.5;
    translation: (0.1, 0.1, 0.0);
    rotation: (90, 0, 0, 1);
    Enabled: True);

var
  buffer: Pointer;
begin
  memcpy(buffer, @UBORec.translation, 48);
  memcpy(buffer + 12, @UBORec.scale, 4);
  //  move(@UBORec.scale, buffer+12, 4)
Move() steht schon beim +12 an.
Mit Move() bin ich immer am üben, bis es endlich mal klappt,

Code: Alles auswählen

Move(UBORec.scale, (PByte(buffer) + 12)^, 4)
FPC Compiler Entwickler

Warf
Beiträge: 1913
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: memcpy, gibts nicht, ? [ gelöst ]

Beitrag von Warf »

PascalDragon hat geschrieben:
So 17. Sep 2023, 18:55

Code: Alles auswählen

Move(UBORec.scale, (PByte(buffer) + 12)^, 4)
Ich finde bei sowas sollte man die Pointer Array syntax benutzen:

Code: Alles auswählen

Move(UBORec.scale, PByte(buffer)[12], 4)
Ich finde pointer arithmetik immer verwirrend, was bedeutet +12, bedeutet das den Pointer wert um 12 erhöhen, oder um 12*sizeof(p^) (ich glaube es ist das letztere, müsste es aber nochmal nachschauen). Bei der Array syntax ist klar, 12 elemente des Arrays später

Mal ganz davon abgesehen das es für mich die gehardcodedeten Größen (wie die 4 die in dem Fall annimmt das der TGLFloat ein Single ist), auch nach einer Potentiellen Fehlerquelle schreien

Mathias
Beiträge: 6209
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: memcpy, gibts nicht, ? [ gelöst ]

Beitrag von Mathias »

Danke, jetzt gehts.

Code: Alles auswählen

var
    buffer: PChar;
begin
....   
  move(UBORec.translation, buffer[offset[0]], SizeOf(TUBORec.translation));
  move(UBORec.scale, buffer[offset[1]], SizeOf(TUBORec.scale));   
wie die 4 die in dem Fall annimmt das der TGLFloat ein Single ist
Du hast recht, man sollte immer SizeOf nehmen.

Die Vorlage die ich da hatte es eh ein gewurstel.
Besser, man passt den Record so an, das er genau das Abbild des Buffers hat.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

PascalDragon
Beiträge: 834
Registriert: Mi 3. Jun 2020, 07:18
OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
CPU-Target: Aarch64 bis Z80 ;)
Wohnort: München

Re: memcpy, gibts nicht, ? [ gelöst ]

Beitrag von PascalDragon »

Warf hat geschrieben:
So 17. Sep 2023, 19:06
PascalDragon hat geschrieben:
So 17. Sep 2023, 18:55

Code: Alles auswählen

Move(UBORec.scale, (PByte(buffer) + 12)^, 4)
Ich finde bei sowas sollte man die Pointer Array syntax benutzen:

Code: Alles auswählen

Move(UBORec.scale, PByte(buffer)[12], 4)
Ich finde pointer arithmetik immer verwirrend, was bedeutet +12, bedeutet das den Pointer wert um 12 erhöhen, oder um 12*sizeof(p^) (ich glaube es ist das letztere, müsste es aber nochmal nachschauen). Bei der Array syntax ist klar, 12 elemente des Arrays später
Es ist letzteres, genau wie beim Zugriff über Array.
FPC Compiler Entwickler

Mathias
Beiträge: 6209
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: memcpy, gibts nicht, ? [ gelöst ]

Beitrag von Mathias »

So wie es aussieht, ist der Unterschiede zwischen C und Pascal.
Bei C muss man den Pointer der Variable mitgeben, und bei Pascal ist es die Pure Variable
Und Src und Dest ist auch vertauschst.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Antworten