The nature of VB string as parameter transmission in API
Question background:
I saw a question in the forum a few days ago, the content is:
The code in the module:
Option expedition
Public Declare Function GetComputername lib "kernel32" Alias "getcompuffer as string, nsize as long) AS long 'declares an API function for computer name
Code in the form:
Option expedition
Private submmand1_click ()
DIM Computername As String
DIM Length As Long
Length = 255
Str = String (Length, 0)
Getcomputername Computername, Length
Debug.print computename,
End Sub
The functionality of the above program is to get the computer name.
Everyone looks at the lpbuffer of the API in the API is declared as a ByVal (pass value). Then after the call, the API function can be sent back to the computer name by computername, then the medlar is not declared as a pass value call mode? The change in the phedular nip does not affect the argument, but the API function can be returned to the value after calling the API function. What is the reason?
related information:
Everyone knows that there is no pointer type in the C language in the VB. Only the character data type in the C language, that is, the character variable can only store one character, and there is no string variable, which is implemented by the character string, which is characterized by '/ 0' to determine whether the character is ending. of. The VB has a string variable type, a growing, one is a fixed length. And the VB string specifically automatically protects.
For example: DIM STR AS STRING * 6
Str = "abcdef"
Debug.print str 'will display Abcdef
Str = "abcdefghijklmnopq"
Debug.print str 'also displays AbcDef, indicating that it has a protection function, cut more than characters
The characters used in VB are a string pointer type called BSTR format.
6 A b D e f chr (0)
The character descriptor is used by VB, and the BSTR pointer directly points to the first character.
Because most API functions are written in C or C , a pointer called LPSTR type is used in C / C (API).
Storage state diagram of string variables in memory in VB:
As can be seen from the above: The address of the string variable x is different from the address of the actual string, that is, the first address of the string in the character X variable is actually the same as C / C . In fact, the descriptor of Descriptor is the string pointer address in C. When the BSTR pointer is ignored by the LPSTR pointer, the BSTR can be passed to the API when the API is called. When passing the value of the value, it is actually transmitted is the first address of the string stored in the actual parameters. When the API is called, it can return data by it, and the API modifies the string data pointed to by the address transmitted to it. However, there is no change in the real-reference character variable, so data can be returned. That is, there is no conflict between the parametric change in the frequency value modulation mode specified in the advanced language does not affect the rule of the argument.
Example:
The code in the module:
Option expedition
Public Declare Function GetComputername LIB "Keernel32" Alias "getComputerNamea" code:
Option expedition
Private submmand1_click ()
Dim Str As String
DIM STR1 AS STRING
DIM Length As Long
Length = 255
Str = String (Length, 0)
Str1 = STR
Debug.print Varptr (STR), "", Varptr (STR1)
Debug.Print Strptr (Str), "", Strptr (STR1)
Debug.print
Getcomputername Str, Length
Debug.print Str
Debug.Print Varptr (STR)
Debug.Print Strptr (STR), LEN (STR), LENGTH
End Sub
You can see the run results in the immediate window. The address of the string variable is different from the address of the string.
You can also see the address of the string variable STR and STR1, and the string address is also different, this shows that the assignment operation is not assigned to STR1 but also in memory in memory. String. In the C language, multiple characters pointer variables can point to the first address of the same string.
When the BYVAL LPBUFFER AS STRING method in the API is changed to: Byref LPBuffer AS String, the RMB programming environment will crash when the running program is run.
Map:
Because the address of the variable itself is passed to the API, there is no access to the API when the address of the string is transmitted to the API, so the API causes access errors when modifying the data.
to sum up:
The API cannot be called in an addressing method. If the address method is used, it is the pointer to the pointer. The API will not return data and cause access to error, so you need to deliver a string pointer with ByVal.