Bonjour à tous,
J'aimerai savoir s'il existe un équivalent à la fonction CopyMemory() de Delphi sous Windows pour Lazarus sous Linux. Si non, quelle pourrait être la solution de remplacement ?
Bonne journée à tous,
Slander
Bonjour à tous,
J'aimerai savoir s'il existe un équivalent à la fonction CopyMemory() de Delphi sous Windows pour Lazarus sous Linux. Si non, quelle pourrait être la solution de remplacement ?
Bonne journée à tous,
Slander
Bonjour,
je remonte ce vieux topic parce que google me l'a remonté, malheureusement j'ai le don pour trouver des discussions moisies...
Qu'on en juge :
Déjà, avec une réponse aussi laconique, le pauvre OP a dû souffrir, et on constate que la discussion n'est pas résolue...
Essayons donc tous ensemble de trouver une solution (pas pour l'OP, ça a dû être résolu, vous pensez, 7 ans déjà...).
La doc MSDN indique pour le CopyMemory :
Méfiance avec l'utilisation de move car on trouve dans systemh.inc la ligne Procedure Move(const source; var dest; count:SizeInt);
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 void CopyMemory( _In_ PVOID Destination, _In_ const VOID *Source, _In_ SIZE_T Length );
Bonjour les inversions source et destination, alors attention lors de l'écriture du code !
Bon, je mets ça en place dans mon code (System.Move(aPixels, SrcBmp.ScanLine[SrcBmp.Height -1], IMAGE_HEIGHT*IMAGE_WIDTH*SizeOf(TRGBQuad));, voir là pour les détails), évidemment je me prends un AV (sinon je ne serais pas là), je continue à fouiller, voilà que je trouve une discussion sympatoche :
J'essaye avec mon code, ça ne compile pas à cause des chapeaux ("illegal qualifier" sur la source)...The code work well under Windows but under Linux I get an exception on Move instruction.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 var gbuff: Pointer; ... GetMem(gbuff, s); {$ifdef Win32} CopyMemory(gbuff, FImage.Bits, s); {$endif} {$ifdef Linux} Move(FImage.Bits, gbuff, s); {$endif}
[réponse :]
Move procedure from RTL takes dereferenced pointers as arguments, so you'll need to use it this way:
Move(FImage.Bits^, gbuff^, s);
Je les enlève tous les deux, ça compile mais AV à l'exécution.
Je ne remets que le second, ça compile mais AV à l'exécution.
Et cerise sur le gâteau, contrairement à ce que disait le posteur de cette discussion ("The code work well under Window"), j'ai testé et gagné les AV's sous.. Windows !
Voilà... Même pas j'essaye sous Linux.
Si quelqu'un a une idée, il est le bienvenu.
CopyMemory travaille avec des pointeurs, Move avec des instances
il ne faut pas lui donner l'adresse de la ScanLine mais la données pointée
Code : Sélectionner tout - Visualiser dans une fenêtre à part System.Move(aPixels, SrcBmp.ScanLine[SrcBmp.Height -1]^, IMAGE_HEIGHT*IMAGE_WIDTH*SizeOf(TRGBQuad))
(en supposant que aPixels est un tableau statique)
ceci dit, ça ne fonctionnera que si le bitmap est en 32bits
Merci pour les explications, mais tu n'as pas lu mon post jusqu'au bout :
Comme ça, tu veux dire ? C'est en place, c'est en place...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 with SrcBmp do begin SrcBmp.PixelFormat:=pf32bit;
après j'ai envie de dire, quel est l'intérêt ?
si tu veux utiliser le ScanLine d'un Bitmap tu peux le faire directement
étrangement sous Lazarys c'est ScanLine[0] qui pointe sur le début du bitmap et non ScanLine[H - 1] comme sous Delphi (Bitmap avec la tête en bas)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 const W = 256; H = 256; type TPixels = array[0..H - 1, 0..W - 1, 0..3] of Byte; PPixels = ^TPixels; var Bmp : TBitmap; Pixels: PPixels; x, y : Integer; begin Bmp := TBitmap.Create; Bmp.pixelFormat := pf32Bit; Bmp.SetSize(W, H); Bmp.BeginUpdate; Pixels := Bmp.ScanLine[0]; // manifestement sous Lazarus il faut prendre ScanLine[0] for x := 0 to W - 1 do begin for y := 0 to H - 1 do begin Pixels^[y, x, 0] := x + y; // blue Pixels^[y, x, 1] := x - y; // green Pixels^[y, x, 2] := x + x; // red Pixels^[y, x, 3] := 255; // alpha end; end; Bmp.EndUpdate(); Image1.Picture.Graphic := Bmp; Bmp.Free; end;
ce qui se confirme dans le code
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 function TRawImage.GetLineStart(ALine: Cardinal): PByte; begin Result := Data; if Result = nil then Exit; if ALine = 0 then Exit; Inc(Result, ALine * Description.BytesPerLine); end;
Partager