
Declaring an array of pointers in Visual Basic (and putting and getting data from it)
You are absolutely right! I thank you a lot. It was not 100% accurate but
99% at least:-). But you should have all credit for the success. VarPtr()
opened up a lot of possibilites. Too bad VarPtr() is not documented in VB so
I took some time reading about how the function and it's siblings work.
There are more hidden functions for you guys to use when dealing with
strings and objects or other complex datastructures. I hade to make a few
changes before it worked but you really gave me the clue in how to bend the
memory to the max in Visual Basic. I was so e{*filter*}d I forgot to go to sleep
last night efter you gave me the tip. Now I have 100% functionality of my
application. I can tell you that the API that I had to call required more
use of VarPtr() so I was really thrilled when I was reminded of it. I have
not really used VB this intense since 2 years ago but I'm pretty sure that I
have been using VarPtr() before when making a callback function with the
AddressOf operator among others.
---------------
For you new into VB make sure that when you define arrays check if Option
Base is 0 or 1. It defaults to 0 so if you write Dim x(10) you get one array
with 11 elements and not 10 as you might think. This is important to know so
you don't unaccidentally overwrite something in the memory and cause a
program crash. It happened to me as I was working with VarPtr().
---------------
Anyway this is how it should look like:
Public Declare MyFunction lib="libraryname" (ByVal lPointers As Long) As
Long
// Important to declare as ByVal if not VB will send the reference since
ByRef is default (this was one of the things I have to change) and also I
decided not to write lPointers() as an array it did not work so I changed to
sending the pointer to the array instead as you can see down below.
---------------
// I need to declare the store of bytes
Dim byteStore() As Byte // Byte store
Dim myArray() As Long // The array which will contain references to the
byte stores defined below
Dim lReturn As Long
Redim byteStore(1868 -1) // Subract one since option base is 0 so we get
an interval of 0-1867
Redim myArray(10 - 1) // I want 10 entries (one for each finger on
your 2 hands)
myArray(6) = VarPtr(byteStore(0)) // Make sure that array will include
the pointer to the byteStore before calling function
// All other entries
in myArray will be 0 and not point to anything
lReturn = MyFunction(VarPtr(myArray(0))) // This is the call and the API
will be notified of the address of myArray
//
And find that index 6 has a pointer to byteStore which contains 1868 bytes
//
ready to recieve data
//
Once again Martin this I had to change to VarPtr() again
//
since the array did not seem
//
to be acknowledged by the API.
Once again, thank you Martin for you excellent knowledge!
---------------
Hans Rasmussen
Quote:
> Declaring an array of pointers in Visual Basic (and putting and getting data
> from it)?
> I have not succeeded in solving a problem calling a DLL from Visual Basic.
> ANY help appreciated especially if it is impossible, or maybe it isn't???
> The C declaration looks like this:
> #define PBRETURN long int
> PBRETURN WINAPI
> pbEnrollWiz(OUT void *templ[10]);
> As I understand the parameter that receives data from the function is an
> array of pointers. I also know that each entry in the array is a pointer to
> either NULL or the pointer is referencing memory allocated by malloc(1868);
> I also know that the DLL and function will use the allocated memory to write
> binary data for each pointer (of the 10 possible) that is not NULL.
> In Visual Basic I therefore need to create an array with 10 entries. Each
> entry should be a pointer to a memory area of 1868 bytes or point to NULL
> (no memory allocated). It's the duty of program to decide with of the 10
> entries I want to receive data in.
> There are several difficulties when trying to do this in VB:
> 1. How do I declare an array of pointers? Can this even be done?
> 2. How do I make sure that some pointers should be NULL and at least one
> pointer I need to reference to an area of 1868 bytes that is allocated with
> malloc(1868)? There is no malloc() in Visual Basic.
> 3. The data received back is not text it's binary data. How can I store
> this? This might be a clue when building the array. Byte datatype in Visual
> Basic only allows me to store 1 byte. Maybe an array of bytes in a Type
> Declaration?
> I really really really hope someone has any clues. If you have anything to
> add please do so. You do not need to come up with a complete solution.
> Sometimes a few tips might help. I have some tips already but since
> everything I try result in a DLL-crash I want to clear my mind totally and
> start over with fresh idas.
> Down below is an example in C calling the Function as described above.
> PBRETURN ret_val;
> void *enrolled_template[10] = {NULL, NULL, NULL, NULL, NULL,
> NULL, NULL, NULL, NULL, NULL}; // All
> pointers point to NULL
> enrolled_template[6] = malloc(1868); // Pointer 6 is initialized with
> malloc() to point to an area large enough for function pbEnrollWiz
> ret_val = pbEnrollWiz(enrolled_template); // pbEnrollWiz will detect that
> Pointer 6 has allocated space and will write back some data to the memory