![]() |
Alternative zu StrpCopy gesucht
Moin, ich suche eine Alternative zu StrPCopy. (will keine SysUtils in der uses)
Delphi-Quellcode:
Ich würde ja die Chars "manuell" in einer For-Schleife umschaufeln, aber gibt es 'ne elegantere Lösung ?
var
s: String; p: PChar; begin s := 'Hallo'; p := PChar(s); p := @S[1]; end. // -------------------- > var s: String; p: array [0..25] of Char; begin s := 'Hallo'; StrPCopy(p, s); p := PChar(s); // <-- Inkompatible Typen: 'Array' und 'PChar' p := @S[1]; // <--- Inkompatible Typen: 'Array' und 'Pointer' end. |
Re: Alternative zu StrpCopy gesucht
|
Re: Alternative zu StrpCopy gesucht
Ein PChar ist auch nullterminierend und die Compilermagic nimmt einem da was ab:
Delphi-Quellcode:
Ansonsten, StrpCopy ruft StrLCopy auf:
procedure TForm1.Button1Click(Sender: TObject);
var s: String; p: PChar; begin s := 'Hello World'; p := PChar(s); ShowMessage(p); end;
Delphi-Quellcode:
Nachtrag:
function StrLCopy(Dest: PChar; const Source: PChar; MaxLen: Cardinal): PChar; assembler;
asm PUSH EDI PUSH ESI PUSH EBX MOV ESI,EAX MOV EDI,EDX MOV EBX,ECX XOR AL,AL TEST ECX,ECX JZ @@1 REPNE SCASB JNE @@1 INC ECX @@1: SUB EBX,ECX MOV EDI,ESI MOV ESI,EDX MOV EDX,EDI MOV ECX,EBX SHR ECX,2 REP MOVSD MOV ECX,EBX AND ECX,3 REP MOVSB STOSB MOV EAX,EDX POP EBX POP ESI POP EDI end; function StrPCopy(Dest: PChar; const Source: string): PChar; begin Result := StrLCopy(Dest, PChar(Source), Length(Source)); end; Das Rumhantieren mit nullterminuierenden Strings ist meist überflüssig. Oft reicht zum Schluss ein Cast nach PChar, Pointer oder in dem man einen Zeiger auf das erste Zeichen des Strings angibt:
Delphi-Quellcode:
var
s: String; begin s := 'Hello world'; Messagebox(hWnd, PChar(s), ... Messagebox(hWnd, Pointer(s), ... Messagebox(hWnd, @s[1], ... |
Re: Alternative zu StrpCopy gesucht
Moin!
Richtig, wenn man einen PChar übergeben will. Was ist aber nun, wenn man einen Buffer übergeben bekommt, den man mit einem PChar füllen soll? Ein typecast ist da dann nicht anwendbar, da er einen eigenen Speicherbereich angibt und nicht den fremdalloziierten, übergebenen Speicher nutzt. Das ist ein grosses Manko was gegen die Compiler Magic bei PChar's spricht. In dem Falle ist man notgedrungen auf StrPCopy() o.ä. angewiesen kann eben mal nicht so einfach ein PChar() TypeCast in den Quelltext schmieren... MfG Muetze1 |
Re: Alternative zu StrpCopy gesucht
Thx All, Luckie
|
Re: Alternative zu StrpCopy gesucht
Moin moin,
die Frage ist schon beantwortet, aber mal Interesse halber: Was spricht dagegen, es für das Beispiel von Matti (turboPASCAL) so zu machen?
Delphi-Quellcode:
// .. procedure TForm1.Button1Click(Sender: TObject); type PArrayOfChar = ^TArrayOfChar; TArrayOfChar = array[0..25] of Char; var szStr : String; ArrayOfChar : array[0..25] of Char; begin szStr := 'Hallo'; TArrayOfChar(ArrayOfChar) := PArrayOfChar(Pointer(szStr))^; ShowMessage(ArrayOfChar); end; |
Re: Alternative zu StrpCopy gesucht
Vielleicht sollten wir an dieser Stelle nochmal auf Motzis
![]() |
Re: Alternative zu StrpCopy gesucht
Um die Frage von Peter noch schnell zu beantworten, habe ich seinen Code mal in leicht abgeänderter Form:
Code:
...ausgetestet und disassembliert und danach kommentiert. Sollte also auch für Assemblerunkundige verständlich sein.
begin
[color=green]szStr := 'Hallo';[/color] [color=red]TArrayOfChar(ArrayOfChar) := PArrayOfChar(Pointer(szStr))^;[/color] [color=blue]MessageBox(0, ArrayOfChar, ArrayOfChar, 0);[/color] end.
Code:
Ich habe den Code ausführlichst kommentiert. Einfach mal reinschauen.
[color=gray]CODE:004038D4 start:
CODE:004038D4 push ebp CODE:004038D5 mov ebp, esp CODE:004038D7 add esp, 0FFFFFFF4h CODE:004038DA push esi CODE:004038DB push edi CODE:004038DC mov eax, offset dword_4038AC CODE:004038E1 call @Sysinit@@InitExe$qqrv ; Sysinit::__linkproc__ InitExe(void) CODE:004038E6 xor eax, eax CODE:004038E8 push ebp CODE:004038E9 push offset ExceptionHandler CODE:004038EE push dword ptr fs:[eax] CODE:004038F1 mov fs:[eax], esp[/color] ; ------------------------------------------------------------------------ [color=#80FF80][b]; Hier wird in den Registern (Aufrufkonv. "register") der literale und der ; Zielstring übergeben![/b][/color] [color=green]CODE:004038F4 mov eax, offset szStr ; Destination CODE:004038F9 mov edx, offset aHallo ; Source (literal string) CODE:004038FE call @System@@LStrAsg$qqrv ; System::__linkproc__ LStrAsg(void)[/color] ; ------------------------------------------------------------------------ [color=#FF8080][b]; Diese 2 Zeilen könnte man in eine stecken, aber das soll mal egal sein, ; wichtig ist, daß hier der Pointer auf den Puffer des Strings in ; ESI (Quellpointer-Register) geladen wird[/b][/color] [color=red]CODE:00403903 mov eax, ds:szStr CODE:00403908 mov esi, eax ; Init ESI[/color] [color=#FF8080][b]; Hier wird das Offset auf den Puffer - ArrayOfChar - in EDI (Zielpointer-Register) ; geladen.[/b][/color] [color=red]CODE:0040390A mov edi, offset ArrayOfChar ; Init EDI[/color] [color=#FF8080][b]; Anzahl der auszuführenden Wiederholungen[/b][/color] [color=red]CODE:0040390F mov ecx, 6[/color] [color=#FF8080][b]; Wiederhole ECX-mal das Kopieren von jeweils einem DWORD von ESI ; nach EDI[/b][/color] [color=red]CODE:00403914 rep movsd ; Copy 6 DWORDs from CODE:00403914 ; ESI to EDI[/color] [color=#FF8080][b]; Kopiere 2 weitere Bytes ...[/b][/color] [color=red]CODE:00403916 movsw ; Copy 2 more bytes[/color] ; ------------------------------------------------------------------------ [color=#8080FF][b]; "Umgekehrte" Übergabe der Parameter auf den Stack und Aufruf von MessageBox()[/b][/color] [color=blue]CODE:00403918 push 0 CODE:0040391A push offset ArrayOfChar CODE:0040391F push offset ArrayOfChar CODE:00403924 push 0 CODE:00403926 call MessageBoxA_0[/color] [color=gray]CODE:0040392B xor eax, eax CODE:0040392D pop edx CODE:0040392E pop ecx CODE:0040392F pop ecx CODE:00403930 mov fs:[eax], edx CODE:00403933 push offset loc_403940 CODE:00403938 CODE:00403938 locret_403938: ; CODE XREF: CODE:0040393Ej CODE:00403938 retn[/color] Fazit: Es spricht nichts dagegen. Offenbar ermöglicht der Compiler eine Zuweisung eines Zeichenarrays an ein anderes Zeichenarray indem dies transparent in einen Kopiervorgang (zudem einen effektiven - weil ohne zusätzlichen Aufruf) übersetzt wird. Es spricht also nichts dagegen :zwinker: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:10 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