08-07-2013 02:51 PM
Hey all,
While I am finally getting the hang of LabVIEW, I only really know the basics of C, especially when it comes to pointers/dereferencers, and interfacing those things with labview.
I have a DLL that I imported into labview using the wizard. I need data from one of the library calls to be used as input for another library call. However, the output from the first library call is a "pointer to a double pointer" and the input for the second one should simply be a pointer. Do I need to dereference the output of the first function? I tried to use the GetValueByPointer function provided in the Labview utilities but it caused Labview to crash.
The details of the library functions as well as the VI I have so far are attached.
Thanks!
Solved! Go to Solution.
08-07-2013 02:52 PM
I also tried to use MoveBlock but it didn't seem to be able to handle pointers to pointers
08-07-2013 03:19 PM
Seems to me you'd need to use MoveBlock twice, first to get the second pointer using the first, then to use the second pointer to get the final thing pointed at.
08-07-2013 03:53 PM
This is an interesting problem in that the function is returning data to memory it allocates, in an inconvenient format.
The VI you uploaded isn't helpful, since it doesn't show any of the calls to the DLL, and you didn't include the subVIs that make those calls.
You can combine the approaches for 2D Arrays and strings described here: https://decibel.ni.com/content/docs/DOC-9091. The difference is that the first for loop will need to be a while loop, where you stop when the dereferenced value is null, because you don't know the number of items in the array to begin. Then, you'll use the method for dereferencing strings in a for loop, once for each element in the array generated in the initial while loop. It will look like this:
There's a way to do this with MoveBlock, too, but it is much more difficult because you'll have to find the end of the strings.
08-07-2013 05:16 PM - edited 08-07-2013 05:19 PM
Thanks for the help... theoretically, that sounds like it should work.
I set this up, but in order to do so I had to change the parameter of the Call Library function to a 64 bit integer from a string (what the import wizard set it as).
LabVIEW didn't like this very much and crashed as soon as the function call was made.
I tried an 8-bit unsigned integer too, since that's what the data type of the pointer is, supposedly. Still no dice.
08-07-2013 05:39 PM - edited 08-07-2013 05:58 PM
For what it's worth, when I called the DLL with the output as a string (i checked in the Call Library function, and it is apparently a "C String Pointer"), i get the value "ÀW\ûþ". Whatever that means. I thought the pointer was only supposed to be one byte/char?
Edit: I found the "string to byte array" function... that's a start.
08-07-2013 06:11 PM
It would help to post the VI that calls enumerateUSB, I can't follow your comments about strings. There's no reason you'd be using string to byte array here. The wacky string value is the result of taking a value that is actually a memory address and trying to display it as text.
Ignore whatever the DLL import function is doing here. Configure the Call Library Function Node so that you're passing the serialList parameter as a pointer-sized integer, passed by pointer. The value that's returned will be a pointer to the first string. When you increment that value by 4 bytes (or 8, on a 64-bit platform), you'll have a pointer to the second string, etc.
A pointer is a 32-bit value on a 32-bit platform, and a 64-bit value on a 64-bit platform. The eventual target of the pointer doesn't matter in the initial DLL call, you only care about passing around numbers which are actually memory addresses. The value in serialList is the first element of a null-terminated array of memory addresses (ie, an array of U32 or U64), which you need to dereference to get to the strings (which are null-terminated arrays of bytes/chars).
08-07-2013 06:45 PM - edited 08-07-2013 06:49 PM
Thank you so much.
I had tried all of that beforehand, but I was passing it as a value and not a pointer, causing it to crash. D'oh.
The rest works great... the only thing you missed was that the next function accepts a pointer, not just the string, so the second loop was unnecessary. Still works out though!
Embarrassing that this all came down to confusion with datatypes!