Click here to Skip to main content
Licence 
First Posted 3 Sep 2000
Views 290,758
Bookmarked 54 times

How to do pointers in Visual Basic

By | 3 Sep 2000 | Article
Show how to use pointers in a C like manner

Introduction

Most people think that Visual Basic does not have pointers and hence is not capable of handling data structures that require pointers (by the way these data structures can be implemented using classes).

Well, they are right but not for very long. Since Visual Basic has access to the entire Win32 API it is not so difficult to equip it with pointers. Let's look at a simple code fragment in C and then at its Visual Basic equivalent.

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char* argv[])
{
    int * ptr;                        //1               
    ptr=(int *)malloc(sizeof(int));   //2             
    *ptr=10;                          //3             
    printf("The address of ptr is %d and its values is %d\n",ptr,*ptr); //4
    free(ptr);                        //5
    return 0;
}

I have marked the lines with numbers so you ,the reader, can follow more easily.

The equivalent of the first line, in VB is:

dim ptr as long   'int * ptr; 

This was easy because it follows from the definition of the pointer. A pointer is just a variable whose value is the address of another variable. It is long because a pointer in MS Windows is 4 bytes.

The second line:

ptr=(int *)malloc(sizeof(int)); 

Well, how do we allocate memory dynamically in Visual Basic? malloc has no equivalent. Here we'll use the Win32 API function HeapAlloc(...).Please check the documentation for more information on it.

So here's our code:

Dim hHeap As Long hHeap = GetProcessHeap()
ptr=HeapAlloc(hHeap,0,2) 'an integer in Visual Basic is 2 bytes

We can even check if memory was allocated.

if ptr<>0 then 
    'memory was allocated
    'do stuff
end if

Now,

*ptr=10;

In Visual Basic we'll use the function CopyMemory which is declared like so:

Public Declare Sub CopyMemory Lib "kernel32" Alias _
    "RtlMoveMemory" (Destination As Any, Source As Any, _
    ByVal Length As Long)

Here's the little trick : I modify the parameters and have two more definitions.

'to write to memory
Public Declare Sub CopyMemoryWrite Lib "kernel32" Alias _
    "RtlMoveMemory" (Byval Destination As long, Source As Any, _
    ByVal Length As Long)

' to read from memory
Public Declare Sub CopyMemoryRead Lib "kernel32" Alias _
    "RtlMoveMemory" (Destination As Any,byval Source As Long, _
    ByVal Length As Long)

Now here's how,

*ptr=10;

translates into Visual Basic.

dim i as integer 
i=10
CopyMemoryWrite ptr,i,2 ' an intger is two bytes

Now towards line 5.

'printf("%d\n",*ptr);
dim j as integer
CopyMemoryRead j,ptr,2
MsgBox "The adress of ptr is " & cstr(ptr) & _
    vbCrlf & "and the value is " & cstr(j)

Now free the memory

HeapFree GetProcessHeap(),0,ptr

Here is the complete listing of the source code: (just copy it into a project and run it).

Option Explicit

Private Declare Sub CopyMemory Lib "kernel32" _
    Alias "RtlMoveMemory" (Destination As Any, _
    Source As Any, ByVal Length As Long)
Private Declare Function GetProcessHeap Lib "kernel32" () As Long
Private Declare Function HeapAlloc Lib "kernel32" _
    (ByVal hHeap As Long, ByVal dwFlags As Long,_
     ByVal dwBytes As Long) As Long
Private Declare Function HeapFree Lib "kernel32" _
    (ByVal hHeap As Long, ByVal dwFlags As Long, lpMem As Any) As Long
Private Declare Sub CopyMemoryWrite Lib "kernel32" Alias _
    "RtlMoveMemory" (ByVal Destination As Long, _
    Source As Any, ByVal Length As Long)
Private Declare Sub CopyMemoryRead Lib "kernel32" Alias _
    "RtlMoveMemory" (Destination As Any, _
    ByVal Source As Long, ByVal Length As Long)

Private Sub Form_Load()
    Dim ptr As Long   'int * ptr;
    Dim hHeap As Long
    hHeap = GetProcessHeap()
    ptr = HeapAlloc(hHeap, 0, 2) 'an integer in Visual Basic is 2 bytes
    If ptr <> 0 Then
    'memory was allocated
    'do stuff
        Dim i As Integer
        i = 10
        CopyMemoryWrite ptr, i, 2 ' an intger is two bytes
        Dim j As Integer
        CopyMemoryRead j, ptr, 2
        MsgBox "The adress of ptr is " & CStr(ptr) & _
            vbCrLf & "and the value is " & CStr(j)
        HeapFree GetProcessHeap(), 0, ptr
    End If
End Sub

Bonus

Here is a simple and not complete implementation of a linked list. (On the form put a Command button named Command1)

Option Explicit
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory"_
    (Destination As Any, Source As Any, ByVal Length As Long)
Private Declare Function GetProcessHeap Lib "kernel32" () As Long
Private Declare Function HeapAlloc Lib "kernel32" _
    (ByVal hHeap As Long, ByVal dwFlags As Long, _
    ByVal dwBytes As Long) As Long
Private Declare Function HeapFree Lib "kernel32" _ 
    (ByVal hHeap As Long, ByVal dwFlags As Long, _
    lpMem As Any) As Long
Private Declare Sub CopyMemoryPut Lib "kernel32" Alias _
    "RtlMoveMemory" (ByVal Destination As Long, _
    Source As Any, ByVal Length As Long)
Private Declare Sub CopyMemoryRead Lib "kernel32" Alias _
    "RtlMoveMemory" (Destination As Any, _
    ByVal Source As Long, ByVal Length As Long)

Dim pHead As Long
Private Type ListElement
    strData As String * 255 '==255 * 2=500 bytes  vbStrings are UNICODE !
    pNext As Long  '4 bytes
                'pointer to next ; ==0 if end of list
'----------------
'total: 504 bytes
End Type

Private Sub CreateLinkedList()
'add three items to list
' get the heap first
    Dim pFirst As Long, pSecond As Long 'local pointers
    Dim hHeap As Long
    hHeap = GetProcessHeap()
    'allocate memory for the first and second element
    pFirst = HeapAlloc(hHeap, 0, 504)
    pSecond = HeapAlloc(hHeap, 0, 504)
    If pFirst <> 0 And pSecond <> 0 Then
    'memory is allocated
        PutDataIntoStructure pFirst, "Hello", pSecond
        PutDataIntoStructure pSecond, "Pointers", 0
        pHead = pFirst
    End If
    'put he second element in the list
End Sub

Private Sub Command1_Click()
    CreateLinkedList
    ReadLinkedListDataAndFreeMemory
End Sub

Private Sub PutDataIntoStructure(ByVal ptr As Long, _
        szdata As String, ByVal ptrNext As Long)
Dim le As ListElement
    le.strData = szdata
    le.pNext = ptrNext
    CopyMemoryPut ptr, le, 504
End Sub

Private Sub ReadDataToStructure(ByVal ptr As Long, _ 
        struct As ListElement)
Dim le As ListElement
    CopyMemoryRead le, ptr, 504
    struct.strData = le.strData
    struct.pNext = le.pNext
End Sub

Private Sub ReadLinkedListDataAndFreeMemory()
Dim pLocal As Long
Dim hHeap As Long
Dim le As ListElement
Dim strData As String
    pLocal = pHead
    hHeap = GetProcessHeap()
    Do While pLocal <> 0
        ReadDataToStructure pLocal, le
        strData = strData & vbCrLf & le.strData
        HeapFree hHeap, 0, pLocal
        pLocal = le.pNext
    Loop
    MsgBox strData
End Sub

Private Sub Form_Load()

End Sub

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Stefan Savev



Bulgaria Bulgaria

Member



Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
GeneralWhy Pinmembermitchell5015:27 20 Dec '06  
GeneralRe: Why Pinmembercodemind22:11 18 Nov '07  
QuestionHow to execute a .exe file from resource without extracting it to a file PinmemberRahul A. H.0:24 28 Oct '06  
AnswerRe: How to execute a .exe file from resource without extracting it to a file PinmemberMassimo Conti6:39 10 Dec '06  
GeneralEasier way to dynamic allocation Pinmemberx1372938820:53 19 Aug '06  
GeneralRe: Easier way to dynamic allocation Pinmemberdarkoverlordofdata4:37 21 Sep '06  
QuestionHow to allocate memory in A.exe, send to and deallocate in B.exe? [modified] Pinmemberehaerim11:00 7 Aug '06  
Hi all,
 
What I have to do is as follows:
1) There are two processes: A.exe and B.exe
2) A.exe allocates a memory block of bytes (131 bytes) using HealAlloc WinAPI.
3) A.exe sends it to B.exe using SendMessage/WM_COPYDATA.
4) B.exe receive, processes and finally deallocates it using HeapFree WinAPI.
 
That's right! A.exe allocates, but B.exe deallocates it.
 
I've coded as follows, but failed to get what I wanted. Please someone help me on this.
 
1) A.exe declares a local Byte array variable (Total_PL) to store the data to send to B.exe, and fills it with some information.
 
Dim TOTAL_PL(0 To 130) As Byte
Dim Sbj As String * 32
Dim Series As String * 15
Dim DateTime As String * 16
 
Sbj = "This is a subject"
Series = "TOTAL_PL"
DateTime = Format(Now, "YYYYMMDD00HHMMSS")
 
CopyMemory(Total_PL(0), 131, 4) ' first 4 bytes will have the total length of data => 131
CopyMemory(Total_PL(4), 5, 1) ' second 1 byte will have data type => 5
Call CopyMemory(Total_PL(5), 0, 2) ' 0
Call CopyMemory(Total_PL(7), 0, 4) ' 0
Call CopyMemory(Total_PL(11), 0, 2) ' 0
Call CopyMemory(Total_PL(13), 0, 4) ' 0
Call CopyMemory(Total_PL(17), 0, 2) ' 0
Call CopyMemory(Total_PL(19), 0, 1) ' 0
Call CopyMemory(Total_PL(20), 0, 4) ' 0
Call CopyMemory(Total_PL(24), 0, 4) ' 0
Call CopyMemory(Total_PL(28), 67, 2) ' actual Data lenght => 67
Call CopyMemory(Total_PL(30), &HFFFE, 2) ' &HFFFE
Call CopyMemory(Total_PL(32), ByVal Sbj, Len(Sbj)) ' "This is a subject"

Call FillMemory(Total_PL(64), 2, Asc(" ")) ' two blanks
Call CopyMemory(Total_PL(66), ByVal Series, Len(Series)) ' "TOTAL_PL"
Call CopyMemory(Total_PL(81), htonl(0), 4) '
Call CopyMemory(Total_PL(85), ByVal "01", Len("01")) ' "01"
Call CopyMemory(Total_PL(87), htonl(&HF1F2F3F4), 4) ' &HF1F2F3F4 in network byte order
Call CopyMemory(Total_PL(91), htonl(&HE1E2E3E4), 4) ' &HE1E2E3E4 in network byte order
Call CopyMemory(Total_PL(95), htonl(0), 4) ' 0
Call CopyMemory(Total_PL(99), htonl(0), 4) ' 0
Call CopyMemory(Total_PL(103), htonl(0), 4) ' 0
Call CopyMemory(Total_PL(107), CDbl(0), 8) ' 0.0 as Double
Call CopyMemory(Total_PL(115), ByVal DateTime, Len(DateTime)) ' Date and Time

 
2) Now, A.exe allocates a memory block from heap using HeapAlloc.
 
Dim pTotal_PL As Long
 
pTotal_PL = HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS Or HEAP_ZERO_MEMORY, 131)
If pTotal_PL = 0 Then
Debug.Print "memory allocation failed!"
Exit Sub
End If
 
3) CopyMemory Total_PL into pTotal_PL.
 
Call CopyMemory(pTotal_PL, VarPtr(Total_PL(0)), 131)
 
The reason why I do like in 1) through 3) is because I don't know how to do it directly using pTotal_PL alone. If you know, just let me know how please.
 
4) Fill COPYDATASTRUCT and SendMessage/WM_COPYDATA to B.exe.
 
Dim cds As COPYDATASTRUCT
With cds
.dwData = 2 ' Don't worry about this value. It has meaning only to me.
.cbData = 131 ' size of data to be sent
.lpData = pTotal_PL ' VarPtr(Total_PL(0))
End With
 
Dim nSbId As Long
Dim WinWnd As Long
 
nSbId = &HFFFE
WinWnd = FindWindow(vbNullString, "B.exe")
 
Call SendMessage(WinWnd, WM_COPYDATA, nSbId, cds)
 

5) B.exe receives 131 bytes from A.exe, processes it as it wishes, and finally deallocates it using HeapFree somehow.
 

6) For your reference, please see http://www.thescarms.com/vbasic/PassString.asp[^].
 

I've tried everything I could, but failed yet. Please someone write A.exe and B.exe source code for me. I really appreciate it.
 
LHR
 

 
-- modified at 17:30 Monday 7th August, 2006
AnswerRe: How to allocate memory in A.exe, send to and deallocate in B.exe? Pinmemberehaerim6:02 8 Aug '06  
GeneralRe: How to allocate memory in A.exe, send to and deallocate in B.exe? PinmemberJustBurn18:10 23 Sep '06  
GeneralGreat! Pinmemberdivyakolus4:14 10 Oct '05  
GeneralOption Explicit Pinmemberhuseyin_akturk6:54 1 Feb '05  
GeneralRe: Option Explicit PinsussAnonymous5:23 11 May '05  
GeneralMemory Leak PinmemberRobert Fearn23:21 30 Nov '04  
GeneralCopyMemory in HTML/Browser VBScript Pinmemberomjar9:53 24 Aug '04  
Generalpointer to structure in visual basic PinmemberJoe_valenz13:16 11 Jun '04  
Generaldumping content of allocated data to a file PinsussAnonymous3:04 17 Mar '04  
Generalasp-serverside-messagebox Pinmemberomsss18:24 1 Feb '04  
Generalasp-serverside-messagebox PinsussAnonymous18:23 1 Feb '04  
GeneralName of a variable in a variable!!! PinsussSrikV17:41 20 Jan '04  
GeneralRe: Name of a variable in a variable!!! Pinsuss¨a¨a¨a9:05 12 Feb '04  
GeneralRe: Name of a variable in a variable!!! Pinmemberrohitfredrick13:13 8 Sep '05  
QuestionSize of a picture? PinsussAnonymous12:35 18 Nov '03  
Questionwhat is pHead Pinmemberhesterloli16:08 12 Nov '03  
Questionresolution by a pointer? Pinsussrfcapo4:21 16 Aug '03  
Generalsize of an object in vb PinsussAnonymous4:43 4 Apr '03  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web03 | 2.5.120529.1 | Last Updated 4 Sep 2000
Article Copyright 2000 by Stefan Savev
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid