Eliminating ObjPtr, VarPtr, and StrPtr

Eliminating ObjPtr, VarPtr, and StrPtr

Visual Basic 6 supports the undocumented functions ObjPtr, StrPtr, and VarPtr. These functions return the memory address of the location where the corresponding object, variable, or string is stored. This memory address, also known as a pointer, can then be passed to Windows APIs that accept memory addresses as parameters. Not surprisingly, these functions are rarely used, and also not surprisingly, programmers can get into real trouble using them, since they bypass the memory management and safety features of Visual Basic 6.

There is no automatic upgrade for ObjPtr, VarPtr, and StrPtr, but there is a way to achieve the same functionality in Visual Basic .NET. Before continuing, we must warn you that manipulating memory is not a good practice. You shouldn t need to do it; there is almost always a more appropriate workaround that uses safer techniques.

Okay, okay, if you really want to know how to get the memory address in Visual Basic .NET, we ll show you. But remember, this stuff is dangerous! Let s look at some examples. Create a new Visual Basic .NET console application. Our examples will use the default module. We will be using the System.Run time.InteropServices namespace, so at the top of the module, add the following line of code:

Imports System.Runtime.InteropServices

Memory pointer functions are commonly used with the CopyMemory API, so let s add a Declare statement for the API in the declarations section of our module:

Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _ (ByVal lpDest As Integer, ByVal lpSource As Integer, _ ByVal cbCopy As Integer)

After adding this statement, your module should look like the following:

Imports System.Runtime.InteropServices Module Module1     Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _     (ByVal lpDest As Integer, ByVal lpSource As Integer, _     ByVal cbCopy As Integer)      Sub Main()      End Sub End Module

We will be working with our examples inside the Sub Main method. In Visual Basic .NET, variables are garbage-collected and can in theory be moved around in memory arbitrarily by the Garbage Collector. As a result, getting the memory address of a variable poses a problem, since if the Garbage Collector decides to move the variable in memory, the memory address we just retrieved becomes invalid. Luckily, the Garbage Collector provides a method to pin the object in memory so that it won t be moved around. The GCHandle.Alloc method gets a handle to the variable and pins it in memory. The handle s AddrOfPinnedObject method then returns the memory address. Let s see this in action. The following code creates an integer, pins it in memory, displays the memory address of the variable, and then unpins the handle. (You should always unpin the handle when you re finished playing around with the memory address.)

Sub Main()    Dim myInteger As Integer    Dim handle As GCHandle = _       GCHandle.Alloc(myInteger, GCHandleType.Pinned)    Dim address As Integer = handle.AddrOfPinnedObject.ToInt32    MsgBox("The memory address of myInteger is " & address)    handle.Free() End Sub

Let s look at another example. This code creates two strings, gets the memory addresses of each, and then uses the CopyMemory API to copy one string into another:

Sub Main()    Dim src, dest As String    src = "VB Rocks"    dest = "            "    Dim srcHandle As GCHandle = _       GCHandle.Alloc(src, GCHandleType.Pinned)    Dim srcAddr As Integer = srcHandle.AddrOfPinnedObject.ToInt32    Dim destHandle As GCHandle = _       GCHandle.Alloc(dest, GCHandleType.Pinned)    Dim destAddr As Integer = destHandle.AddrOfPinnedObject.ToInt32    CopyMemory(destAddr, srcAddr, Len(src) * 2)    srcHandle.Free()    destHandle.Free()    MsgBox(dest) End Sub

If you run this code, you ll see that the source string is copied into the destination string, which is then shown in a message box. Something to be aware of is that variables are stored differently in Visual Basic .NET than in Visual Basic 6. Notice that when you use the CopyMemory API, the third parameter is the number of bytes to copy, which is double the length of the string. In Visual Basic .NET, strings are stored as Unicode, so each character is stored in 2 bytes. Thus, when copying a string using APIs, you have to specify a number of bytes that is double the string length.



Upgrading Microsoft Visual Basic 6.0to Microsoft Visual Basic  .NET
Upgrading Microsoft Visual Basic 6.0 to Microsoft Visual Basic .NET w/accompanying CD-ROM
ISBN: 073561587X
EAN: 2147483647
Year: 2001
Pages: 179

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net