Just believe me that a handle is not a simple pointer inside a pointer. LabVIEW does something along these lines for handle allocation:
struct {
UHandle handle;
int32 size;
int32 flags;
} hdl_header, *phdl_header;
UHandle DSNewHandle(int32 size)
{
char **hdl = malloc(sizeof(char*));
if (hdl)
{
phdl_header ptr = malloc(size + sizeof(hdl_header));
if (ptr)
{
ptr->handle = hdl;
ptr->size = size;
ptr->flags = some_flags;
*hdl = (char*)ptr + sizeof(hdl_header);
add_heap_manager(DSHEAP, hdl);
}
else
{
free(hdl);
hdl = NULL;
}
}
return hdl;
}
In subsequent calls to memory manager functions it does use the information in the header such as the size to decide if and how to reallocate memory. Also all handles are added to some internal heap management but pointers not. This is because LabVIEW considers handles to be resizeable but pointers are always fixed size (you don't have a DSReallocPtr() function).
Swapping pointers inside the handle behind LabVIEWs back does create inconsistencies in LabVIEWs memory heap management and will fail sooner or later. This whole memory manager business inside of LabVIEW seems all a little bit overkill nowadays with 32bit OSes and quite good memory management in the OS itself but back in the old days LabVIEW had to run on Windows 3.1 and Mac OS for 68k and there such a flexible and controllable memory management was absolutely mandatory to be able to create a software program like LabVIEW. Actually memory management on the Mac very much resembled the interface LabVIEW does provide. And changing it now would break all sorts of routines all over the place and is therefore no option.
Depending on your DLL you have some options. If you have a synchronous call to retrieve the data, just make the data large enough on the LabVIEW diagram and pass its pointer directly to the DLL function using the Call Library Node.
Otherwise (asynchronous operation) you will have to be a little creative. You can configure a Call Library Node to pass the pointer to a handle to a function. Inside this function you can resize that handle to the size you are expecting to be necessary and store it in some place your asynchronous capture routine can get at it. To keep LabVIEW happy create your own empty handle and pass that back to the diagram in the same parameter you received your input handle in. In the next iteration you swap the incoming handle with the now hopefully filled in handle. You have to make sure that you do not pass back the handle, which is at the moment filled by the asynchronous function though, as that would certainly crash very fast. You would probably use semaphores for this. Once your DLL function returns, LabVIEW is free to do with the returned handle whatever it likes and that always means reusing it for other means or simply deallocating it and that would be fatal if your asynchronous function is still trying to copy data into it.
Rolf Kalbermatter
Rolf Kalbermatter
My Blog 
DEMO, Electronic and Mechanical Support department, room 36.LB00.390