We'll deal with UDTs shortly. We've already dealt with the traps that can bite you by
using the Any keyword for data types, which is why I've explicitly declared the type. I'm
more concerned here with the lpBuffer variable. If you read the documentation on this
call, it will tell you that this is a buffer that the DLL will put file information into.
That's why we declare it as a Byte data type, since it seems very natural to handle file
information in a Byte format. If we had decided to store the file information in a Long
array that would be fine as well, but there are many data conversions that we would have
to deal with. For example, say we needed to read in a file that was 16 bytes long. If we
used a long array, we'd only have 4 elements, but we would have to do some bit
manipulation to separate out each Byte from a Long array element. Since VB doesn't have a
lot of intrinsic bit manipulation functions (especially the really cool ones like
shift-left and shift-right), it's easier to use a type that maps to the file extremely
well.

Now that we've got some of the data declaration issues out of the way, we can tackle
the array issue. If an API is going to fill a buffer for us and we decide to use an array,
we have to pass in the first element of the array to the call. Note that I didn't say
"element 1". It doesn't matter what the first element is - in fact, we could
pass in any element of our array into the call. For example, each of the ReadFile calls
would work in this example:

Dim bytFile(1 to 10) as Byte
Dim bytFile2(1 to 10) as Byte
Dim lngHFile as Long
Dim lngRet as Long
Dim lngTotalBytes as Long
' Code to open the file would go here.
' lngHFile is the handle to the file.
lngRet = ReadFile(lngHFile, bytFile(1), 10&, lngTotalBytes, 0&)
lngRet = ReadFile(lngHFile, bytFile2(6), 5&, lngTotalBytes, 0&)

In the first call, we're trying to read 10 bytes from a file and passing that
information into bytFile. In the second example, we're only reading 5 bytes and we're
starting at element 6. The first five elements in bytFile2 won't be changed after the
second ReadFile call.

When I tried to pass in an array to a DLL the first time, I wrote this:

lngRet = ReadFile(lngHFile, bytFile(), 10&, lngTotalBytes, 0&)

This didn't work. When you pass in an array, VB is actually passing in a pointer to the
element of the array that you specify (which is why the parameter is passed in by
reference). If I had read up on the documentation, I would have saved myself hours of
frustration. I had assumed that the call would be able to "know" what it should
do with my buffer.

The only place you should be concerned with arrays and API calls is telling the DLL how
much space you've allocated. For example, let's rewrite the first call to ReadFile to
virtually guarantee that we crash our application:

Dim bytFile(1 to 10) as Byte
Dim bytFile2(1 to 10) as Byte
Dim lngHFile as Long
Dim lngRet as Long
Dim lngTotalBytes as Long
' Code to open the file would go here.
lngRet = ReadFile(lngHFile, bytFile(1), _
15&, lngTotalBytes, 0&)

In this case, we've told the DLL that there are 5 more elements from the starting point
than what we've allocated for in memory. As we saw with strings, there's no way that the
DLL knows how long your array is - you have to specify that yourself. In this case, the
DLL is going to try and write to elements 11, 12, 13, 14, and 15. However, the area of
memory that exists after our array is off limits, so the chance of a memory exception
occurring is quite high when the DLL goes beyond the array boundaries - if you want to
experiment with this don't forget to save your work.