01-25-2012 04:23 PM
The code looks correct, but getting the details of pointers right can be tricky and of course I can't evaluate that from the screen capture. If it isn't crashing, that's already a good start.
Remove the sequence structure. Use the error wire to get the desired order of execution. Connect the "Capture Return" wire to the case structure selector and remove the local variable. Any time you have a local variable sitting next to its terminal, as you do here, you're doing something wrong. You'll have LESS clutter if you wire it directly. I would likewise connect NumBytes directly from DSNewPtr output to the input of MoveBlock.
01-25-2012 04:45 PM
Done. I was just using the stacked sequence to organize all the dll calls on one screen - I have about 18 of them. This is a temporary mockup anyway.
I have a question though - in the CLF, for DcamCapture, I have pImageBuff data type as an Unsigned Pointer-sized integer, passed by VALUE. I did this without thinking, but shouldn't this be passed pointer-to-value, in theory? In practice, this crashes labview, so that's obviously not right, but I'm not sure why. Perhaps making it pointer-to-value would make this a handle (pointer-to-a-pointer), not a pointer?
01-25-2012 05:06 PM
smercurio_fc wrote:"If" LabVIEW deallocates the memory. That's the real question. I know 2 things: (1) An array is only guaranteed to be in place during a DLL call. (2) As long as you do nothing with a wire (like branching it), LabVIEW doesn't do anything about where that memory is located. So, which one wins out in this case? I can see your point in that given (1), the safe approach is to do what you say. But if (2) is true in this case, is it necessary? I honestly don't know if (2) is true here or not, since I don't know the bowels of the LabVIEW compiler (pick your LabVIEW version). I'm asking here for my own curiosity and education. Never too old to learn.
I can't answer this definitively. My best guess is that (2) is true. The only reason I can imagine LabVIEW needing to move the data on a straight-through wire would be if you requested a huge block of memory and one was not available, in which case the memory manager might relocate data in order to free a larger contiguous chunk. There's also the endianness issue - when passing an array containing elements larger than a byte, LabVIEW will byte and word swap the array values to match Windows. I assume this happens in-place, but I don't think that's guaranteed. (Note to the original poster: if the DLL returns elements larger than a byte, make sure you swap the endianness before you use the data in LabVIEW.)
01-25-2012 05:11 PM
pobrepablo1 wrote:
I have a question though - in the CLF, for DcamCapture, I have pImageBuff data type as an Unsigned Pointer-sized integer, passed by VALUE. I did this without thinking, but shouldn't this be passed pointer-to-value, in theory? In practice, this crashes labview, so that's obviously not right, but I'm not sure why. Perhaps making it pointer-to-value would make this a handle (pointer-to-a-pointer), not a pointer?
When you think about it for a moment, passing the pointer by value makes sense. The DLL expects a numeric value that represents an address in memory. The value on the wire IS an address in memory, so it needs to be passed by value. Passing it by reference means you're passing a pointer to the memory location that contains the address of the block that you actually allocated, as you guessed. It's easy to make this mistake when configuring MoveBlock - the function prototype says it expects two pointers, but in practice, when used this way, you configure it to pass the LabVIEW array by reference and the pointer you allocated (with DSNewPtr) by value.
01-25-2012 05:40 PM
Makes sense. Thanks for your help, Nathan!
05-08-2017 08:15 PM - edited 05-08-2017 08:18 PM
@nathand wrote:
(Note to the original poster: if the DLL returns elements larger than a byte, make sure you swap the endianness before you use the data in LabVIEW.)
This is generally wrong! A LabVIEW array in memory is in whatever endianess is the native endianess for the current platform, and I would be surprised if the DLL is using a different endianess! 🙂
Byte swapping (and word swapping) is needed if you somehow end up with a byte array or string passed to the DLL and then try to typecast the returned bytes into a LabVIEW datatype. Since the Typecast ALWAYS assumes Big Endian on the byte stream side it will byte swap the data during the cast operation on Little Endian machines (all current platforms except the VxWorks based RT platforms which use a PPC CPU). And then you have to endian swap again to undo the Typecast swapping. But you can instead use the Unflatten (or Flatten for the inverse operation) which has an enum input where you can select "native data format" to avoid the double swapping of data reliably (and not having to potentially avoid the extra byte swapping with conditional compile for the Big Endian platforms).