Visual Basic Concepts

Passing Arrays to a DLL Procedure

You can pass individual elements of an array the same way you pass a variable of the same type. When you pass an individual element, it will be passed as the base type of the array. For example, you can use the sndPlaySound procedure to play a series of .wav files stored in an array:

Dim WaveFiles(10) As String
Dim i As Integer, worked As Integer
   For i = 0 to UBound(WaveFiles)
      worked = sndPlaySound(WaveFiles(i), 0)
   Next i

Sometimes you may want to pass an entire array to a DLL procedure. If the DLL procedure was written especially for Automation, then you may be able to pass an array to the procedure the same way you pass an array to a Visual Basic procedure: with empty parentheses. Because Visual Basic uses Automation data types, including SAFEARRAYs, the DLL must be written to accommodate Automation for it to accept Visual Basic array arguments. For further information, consult the documentation for the specific DLL.

If the DLL procedure doesn't accept Automation SAFEARRAYs directly, you can still pass an entire array if it is a numeric array. You pass an entire numeric array by passing the first element of the array by reference. This works because numeric array data is always laid out sequentially in memory. If you pass the first element of an array to a DLL procedure, that DLL then has access to all of the array's elements.

As an example, consider how you can use an API call to set tab stops within a text box There are internal tab stops in multiple-line (but not single-line) text box controls: If the text in the text box contains tab characters (character code 9), the text following the tab character is aligned at the next tab stop. You can set the position of these tab stops by calling the SendMessage function in the Windows API and passing an array that contains the new tab stop settings.

Private Declare Function SendMessageSetTabs Lib _
"user32" Alias "SendMessageA" (ByVal hwnd As Long, _
ByVal wMsg As Long, ByVal wParam As Long, _
lParam As Any) As Long
Const EM_SETTABSTOPS = &HCB

Sub ChangeTabs(anyText As TextBox, tabcount As Integer)
Dim i As Integer
Dim alngTabs() As Long
Dim lngRC As Long
ReDim alngTabs(tabcount - 1)
   For i = 0 To UBound(alngTabs)
      alngTabs(i) = (i + 1) * 96
      ' Set value to specify tabs in "dialog units."
   Next i
   ' Call with null pointer to empty existing
   ' tab stops.
   lngRC = SendMessageSetTabs(anyText.hwnd, _
   EM_SETTABSTOPS, 0, vbNullString)
   ' Pass first element in array; other elements
   ' follow it in memory.
   lngRC = SendMessageSetTabs(anyText.hwnd, _
   EM_SETTABSTOPS, tabcount, alngTabs(0))
   anyText.Refresh
End Sub

When you call this procedure, you specify the name of the text box and the number of tab stops you want to use for the indent. For example:

Private Sub Command1_Click()
   ChangeTabs Text1, 4
End Sub

This approach will also work for string arrays. A DLL procedure written in C treats a string array as an array of pointers to string data, which is the same way Visual Basic defines a string array.

For More Information   For more information on SAFEARRAYs and other Automation data types, see the Microsoft Press book, Automation Programmer's Reference.