Ansistring vs pchar

zhaozj2021-02-12  138

ANSISTRING? PCHAR? Value? Conversion?

Ansistring, Delphi Developer Guide This explanation, Ansistring is a pointer to the string structure in the stack, which shows the allocation of the ANSISTRING. Help this explanation: The long string saves the number of members, PCHAR is not, the long string (relative to the shortstring type, here is ansistring) is the end of NULL, and contains a reference number, Pchar is a simple NULL end String. The assignment between ANSISSTRING is assigning data, and PCHAR assignment is the pointing point of changing the pointer.

Also store LIKE, two types of differences:

String Mage: ---------------------------------------------- ---------- | Reference counting position | Length bit | L | i | k | e | # 0 | --------------------- -----------------------------------

PCHAR MAU: ------------------------- | L | i | k | e | # 0 | --------- ----------------

String's pointer typically points to the first data bit, when accessing the previous reference count and length bit, Word PTR [Eax- $ 04], DWORD PTR [Eax- $ 08], this category of this class.

The conversion between them is written in the Delphi Developer's Guide: You don't need to turn back in String and PCHAR types with strPas and strpcopy. We have talked in front that Ansistring enforces forced into PCHAR. When you want to convert PCHAR to ANSISTRING, you can assign a value directly: stringvar: = pcharvar;

What is the prototype of STRPAS? I quietly tell you, don't tell others! :> Function strpas (const str: pchar): string; begin result: = str; end; haha, funny. Borland has made such a thing ... -_- bb is actually set up for compatibility.

Strpcopy is relatively complicated. It is a replication between PCHAR after converting String into PCHAR.

Function Strpcopy (const: string): Pchar; Begin Result: = Strlcopy (DEST, PCHAR (SOURCE), Length (Source);

StrlCopy is similar to the strcpy in the C language to copy content, so try to use strlcopy to assign PCHAR, because it will protect the scene, use the assignment number, change the pointer to the pointer.

For the introduction of the Delphi Developer Guide, I wrote such a code to verify: var p: pchar; s: string; begin s: = '1234567abcde'; p: = pChar (s); s: = p; showmessage (S); showMessage (p); showMessage (IntestStr (SizeOf (s));

When executed to S: = '1234567Abcde';, the assembly code is as follows:

The first sentence: s: = '1234567Abcde'; 0045B130 8D45FC Lea EAX, [EBP- $ 04] 0045B133 BAB0B14500 MOV EDX, $ 0045B1B00045B140 E8E791FAFF CALL @lstrlasglstrlasg is a string assignment to the built-in function. It is verified that the String inside the String is data COPY.

The second sentence: p: = pchar (s); 0045B13D 8B45FC MOV EAX, [EBP- $ 04] 0045B140 E8FF95FAFF CALL @ LSTRTOPCHAR0045B145 8BD8 MOV EBX, EAX

Into this sentence, LSTRTOPCHAR is not easy to understand, String is converted to PCHAR. Then simply assign the address, the pointer change points.

It's better to convert by PCHAR to String, this is a key point.

The third sentence: s: = p; 0045B147 8D45FC LEA EAX, [EBP- $ 04] 0045B14A 8BD3 MOV EDX, EBX0045B14C E83393FAFF CALL @lstrfrompchat

Lstrfrompchar is a built-in function that converts String by PCHAR.

Entering LStrFromPChar code @ LStrFromPChar00404484 31C9 xor ecx, ecx00404486 85D2 test edx, edx00404488 7421 jz $ 210040448A 52 push edx0040448B 3A0A cmp cl, [edx] 0040448D 7417 jz $ 170040448F 3A4A01 cmp cl, [edx $ 01] 00404492 7411 jz $ 1100404494 3A4A02 CMP CL, [EDX $ 02] 00404497 740B JZ $ 0B00404499 3A4A03 CMP CL, [EDX $ 03] 0040449C 7405 JZ $ 050040449E 83C204 Add EDX, $ 04004044A1 EBE8 JMP - $ 18 // Looped to get a string length. 0040444A4 42 Inc EDX004044A5 42 Inc EDX004044A5 42 Inc EDX004044A6 89D1 MOV ECX, EDX004044A8 5A POP EDX004044A9 29D1 SUB ECX, EDX // The length of PCHAR is obtained. 004044AB E9D4FEFFFF JMP @ lstrfrompcharlen004044B0 C3 RET

Then processes the conversion of the length of String:

@ LStrFromPCharLen00404384 53 push ebx00404385 56 push esi00404386 57 push edi00404387 89C3 mov ebx, eax00404389 89D6 mov esi, edx0040438B 89CF mov edi, ecx0040438D 89F8 mov eax, edi0040438F E8C4FFFFFF call @NewAnsiString NewAnsiString here called to generate a new standard string. We jump over and see how the string is generated. String generates although it is automatic, in fact, the manual claiming PCHAR is similar, and the difference is initialized than the length bit of PCHAR and the reference count.

@ NewAnsiString00404358 85C0 test eax, eax0040435A 7E24 jle $ 240040435C 50 push eax0040435D 83C00A add eax, $ 0a00404360 83E0FE and eax, - $ 0200404363 50 push eax00404364 E8B3E3FFFF call @GetMem // string length obtained after application memory. 00404369 5A pop edx0040436A 66C74402FE0000 mov word ptr [edx eax- $ 02], $ 000000404371 83C008 add eax, $ 08 00404374 5A pop edx00404375 8950FC mov [eax- $ 04], edx // here should be on the length of the bits 00404378 C740F801000000 mov [eax- $ 08] , $ 00000001 / / Here is referenced count 0040437F C3 RET 00404380 31c0 xor Eax, EAX00404382 C3 RET 00404383 90 NOP

Continue LSTRFROMPCHARLEN below the code. 00404394 89F9 mov ecx, edi00404396 89C7 mov edi, eax00404398 85F6 test esi, esi0040439A 7409 jz $ 090040439C 89C2 mov edx, eax0040439E 89F0 mov eax, esi004043A0 E873E5FFFF call Move // ​​Then move this data requires new string of characters string. 004043A5 89D8 mov eax, ebx004043A7 E8E8FEFFFF call @LStrClr // clean NewAnsiString generated temporary string 004043AC 893B mov [ebx], edi004043AE 5F pop edi004043AF 5E pop esi004043B0 5B pop ebx004043B1 C3 ret

ShowMessage directly input String is directly called. ShowMessage (s); 0045B159 8B45FC MOV EAX, [EBP- $ 04] 0045B15C E8638EFDFF CALL SHOWMESSAGE and enters PCHAR, 嗬嗬, then calls the above LStrFromPchar and then call ShowMessage, the other is the same, if the input parameters have no conversion Instead, it entered PCHAR, and the compiler will handle it. ShowMessage (P); 0045B161 8D45F8 lea eax, [ebp- $ 08] 0045B164 8BD3 mov edx, ebx0045B166 E81993FAFF call @ LStrFromPChar0045B16B 8B45F8 mov eax, [ebp- $ 08] 0045B16E E8518EFDFF call ShowMessage

The last sentence: showMessage (INTTOSTR (SIZEOF (s))); if there is no error, it is 4, a pointer length.

Ok, everything is clear. S: = S; use the lstrlasg built-in function to assign a value.

P: = P; address assignment.

P: = pChar (s); call lstract ipChar to convert the address assignment after PCHAR.

S: = P;

This is the most troublesome, calling lstrfrompchar to transform. The length of the PCHAR is first obtained in the code, and then the LStrFromPcharlen is called with String, and the code is first used in the code to generate a temporary string in the heap. Secondly call Move, Copy to the destination string, and finally clean the temporary string.

转载请注明原文地址:https://www.9cbs.com/read-6557.html

New Post(0)