Source: eNet power in Silicon Valley
Most of the system functions of Windows are provided to users in the form of API functions, and the initial compilation of API functions is basically implemented in C language, pointer operations in C language are everywhere in all aspects of Windows programming. The previous low level of VB programmers is very simple: All versions of VB (excluding VB.net) do not support complete pointer operations, therefore, some core Wincows functions cannot be called at all! Microsoft cannot completely encapsulate the functions implemented by APIs in the control library or class library, and does not allow VB programmers to use pointers to call them! So at that time, many program VB programmers that can be implemented using VC could not achieve it, not a level problem, but Microsoft's product policy was at work. In those years, the only advantage of VB was visual interface programming, which achieves a drag-and-drop effect with a large number of controls. However, today, visual programming of C # is almost the same as that of VB, the advantages of interface writing are gone forever. According to the bad reputation of VB6, a large number of VB programmers are transferred to the C # camp. In summary, to fully utilize the energy of windows, we must first master the pointer weapon. We VB programmers need to pointer this sword to penetrate the boss's heart, let them treat us with the same treatment as C # programmers.
I... net pointer Definition
1. Memory Address
Since the VB readers in this article may have never touched the pointer concept, I will briefly describe the definition of the pointer concept here.
Computer data processing is based on memory addresses. The so-called memory address is to artificially number the space in which data can be stored in the memory in byte order, when a program accesses a variable, the computer determines the actual data content stored in the Variable Based on the address of the variable. Table 1 is a hypothetical memory address. We can see that after the computer allocates the byte array a to three consecutive address spaces starting from 2000, the value of the array is carried out in the memory space of the three bytes. The other variable B is a 32-bit integer, so it occupies space of 2003 and 2004 addresses, and a byte type c variable is put in 3070.
Table 1: Hypothetical memory address
Memory Address 0 1 ...... 2000 2001 2002 2003 2004 ...... 3070 ...... The maximum number depends on the memory capacity.
Variable actual data system Reserved System Reserved a B c 70 0
Variable declaration dim a (2) as byte = {a, B, c} dim B as int32 = 70 dim c as byte
2. Definition and function of pointers
1) A pointer is a special variable that stores a memory address number. When an address number is stored in a pointer variable, we call it a pointer pointing to data starting with this address. Because the operating systems such as win98win2000winxp2003 are currently 32-bit, a 32-bit integer memory address is used to record the memory address (which can be expressed in the range of 0 ~ So the actual data stored by the pointer in the above system is a 32-bit integer. (However, the 64-bit Windows system will record the memory address with a 64-bit integer, And the pointer will be stored as a 64-bit integer ).
What is the role of pointers? In the dark age of assembly language and C language (a long time ago ......), Using pointers to store an address, and then storing data based on this address is the best way to get an efficient Program (first, the address is directly used inside the computer for data storage, the computer does not understand the definition of variable names such as A and B in advanced languages. Second, it is very convenient to transmit the address. For example, function parameters are transferred in stack mode, it is much more efficient to import the entire array memory into the stack using an integer of 32 or 16 bits (the DOS system is 16 bits ), but now we don't need to use this base-level program optimization method. The purpose of our study is: Because the API is written in C, therefore, we must find a way to use these functions.
2) In net, pointers do not point to types. The so-called pointing type is the actual data type represented by the pointer address (this is for the C language, in the C language, if a pointer is of the char type, the data pointed to by this pointer is the 16 data stored in the memory range represented by the address value pointed to by the pointer and the address of the last serial number ). That is to say, the net pointer stores an address, and the Data Type represented by this address can be understood as all types of data that can be expressed in the memory space starting with this address. For example, in table 1, if we use a pointer p storing Address 2000, we can understand that p points to a byte type, and its value is; it can also be understood that p points to a three-byte array, and its value is a continuous a, B, c.
Ii. Usage of pointers
In the following section, we assume that the program has included the following statements to reference the namespace for processing pointers in net:
Imports System. Runtime. InteropServices
, GCHandleType. Pinned)
Dim tpObject As IntPtr = thObject. AddrOfPinnedObject () 'gets the pointer to the byte array
'Get a pointer pointing to 32-bit memory data,
'Because the gchandle method can only be used for referenced objects,
'For An int32 equivalent type, you must use a method that encapsulates it as an object to change it to a reference type.
Dim ti32Test As Object = Convert. ToInt32 (0)
'The following statement tells the net garbage collection process not to process ti32test, that is, the memory location of ti32Test remains unchanged.
Dim thObject1 As GCHandle = GCHandle. Alloc (ti32Test, GCHandleType. Pinned)
Dim tpObject1 As IntPtr = thObject1.AddrOfPinnedObject () 'Get the first address of ti32Test
Dim tudtTest1 As DEFUDT_Test
'The structure is a value type variable. To ensure convenient pointer application, we apply
'Get a byte array pointer of the same size as the structure tudtTest1, as long as the space occupied length and structure are the same
'The net inserts additional data bits in the structure encapsulation, so you must use the sizeof method to obtain the actual size of the structure during unmanaged use.
Dim tudtTest (Marshal. SizeOf (tudtTest1) As Byte
Dim thObject2 As GCHandle = GCHandle. Alloc (tudtTest, GCHandleType. Pinned)
Dim tpObject2 As IntPtr = thObject2.AddrOfPinnedObject () 'gets a pointer to the structure
'Here you can write arbitrary code for pointer processing (which will be supplemented in example 2 )......
'After use, you must release the memory block pointed to by the pointer so that the garbage collector can recycle the memory block.
If thObject. IsAllocated Then
ThObject. Free ()
End If
If thObject1.IsAllocated Then
ThObject1.Free ()
End If
If thObject2.IsAllocated Then
ThObject2.Free ()
End If
End Function
In the above example, the pointer process can be summarized:
1. Define a reference variable with a proper Memory Length (for differences between reference variables and value variables, visit vb.net)
2. Use the GCHandle. Alloc method to fix the memory area of the variable.
3. Use the AddrOfPinnedObject of the GCHandle object to obtain the first address of the memory region and assign it to the pointer variable.
4. Operate the pointer
5. Use the free method of the GCHandle object to release the memory area pointed to by the pointer so that the net garbage collector can recycle the memory space.
2. Access to data directed by pointers
In. net, the storage functions that direct pointer to data are encapsulated in the marshal class, the main functions include: Copy, PtrToStringUni, PtrToStructure, OffsetOf, WriteXXX, RreadXXX, etc, specifically, WriteXXX indicates writing XXX type data to the address indicated by the pointer, and ReadXXX is used to read the data of the address indicated by the pointer in the XXX type. Let's look at Example 2. We use these methods to demonstrate how to store and retrieve data for pointers pointing to different types of data in Example 1.
Example 2: demonstrate how to write and read data to and from pointer obtained from Example 1.
Marshal. WriteInt32 (tpObject1, 0, Convert. ToInt32 (77) 'writes a 32-bit integer 77 to the address pointed to by the ti32Test variable
MsgBox ("the value of ti32Test is:" & ti32Test) 'is displayed as 77 because the data of the variable storage address has been changed to 77.
'The following statement is feasible because ti32Test is a 32-bit integer, And the tabytTest array pointed to by tpObject has exactly four elements.
'And each byte element occupies 8 bits, which together are 32 bits, which is the same as the space occupied by ti32Test. This confirms the aforementioned'
'To the net, there is no description of the pointer pointing to the type.
Marshal. WriteInt32 (tpObject, 0, ti32Test)
'The following code interprets the content of the tabytTest byte array as an int32 integer,
'And assign the value to the int32 element in the tudtTest structure.
'Use Marshal. OffsetOf (GetType (DEFUDT_Test), "i32a"). ToInt32 to get the memory offset position of the i32a element in the structure.
'So New IntPtr (tpObject2.ToInt32 + Marshal. OffsetOf (GetType (DEFUDT_Test), "i32a"). ToInt32) is generated temporarily.
'A pointer pointing to the memory address of i32a (this method also shows that the pointer can be calculated in bytes to point to the appropriate variable.
'Marshal. ReadInt32 is used to read a 32 integer from the pointer.
Marshal. WriteInt32 (New IntPtr (tpObject2.ToInt32 + Marshal. OffsetOf (GetType (DEFUDT_Test), "i32a"). ToInt32 ),_
0, Marshal. ReadInt32 (tpObject ))
'Here we can copy the content of the byte array to the real structure.
MsgBox (Marshal. OffsetOf (tudtTest1.GetType, "i32a"). ToInt32)
TudtTest1 = CType (Marshal. PtrToStructure (tpObject2, GetType (DEFUDT_Test), DEFUDT_Test)
MsgBox ("The i32a element value in the tidtTest1 structure is:" & tudtTest1.i32a) 'the newly assigned value 77 is displayed.
3. Crazy pointer Application
Everyone should have a preliminary understanding of the pointer application. Finally, I will end this article with a simple pointer routine. This is the difference between C # And VB.net in the Forum, according to a paragraph given by a man with two stars on his head, VB.net does not have the pointer function.