LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

LabVIEW Memory Space

Solved!
Go to solution

@EthanHenry wrote:

Ah gotcha, but the rest of the logic checks out for this case, correct?


I think so. Basically if you need to interface to a DLL or shared library you have to watch out these things:

 

- if the library uses default alignment and the structure is flat (contains no pointers) (and fixed size arrays or strings are not pointers but correspond to a cluster with the according number of elements in it in LabVIEW) you can simply create the cluster in LabVIEW and pass it to the library as Adapt to Type parameter, except if you are on LabVIEW 32-bit for Windows (there don't exist any other 32-bit platforms anymore except for the ARM based cRIO and sbRIO real-time targets but these use default alignment of 8 bytes too). There you have to explicitly add any filler bytes to align the data elements to its natural boundary. The nice thing is that these structures with filler bytes can also be used on the other platforms. They do not modify the memory layout but simply make implicit alignment explicit.

 

- if you have pointers in a struct things get more nasty because in 32-bit LabVIEW this corresponds to a 4 byte integer but in 64-bit LabVIEW it corresponds to a 8 byte integer and NI specifically refrained from adding an integer datatype that changes size between platform. The only place this is supported is if the pointer is directly passed as a parameter to the Call Library Node. This means that if you need to support both 32-bit and 64-bit you need to use a conditional compile structure and create according clusters for both modes and create one Call Library Node for each bitness to pass the according cluster to it. It's doable but gets quite nasty quickly.

 

- if you need to provide byte packing for elements independent of the bitness and your cluster is flat, you can instead flatten the cluster and pass it to the Call Library node as a Byte Array and Unflatten it after the call to retrieve possible data. If you do want to read the data from the buffer after the call it is important to use a Byte Array passed as C pointer instead of a String passed as C pointer, because for Strings passed in such a way LabVIEW will scan the string contents after the Call Library Node returns for a terminating 0 byte and truncate the string there, corrupting your data. Most structs containing binary data will almost always contain 0 bytes somewhere. 

 

- if you need to do the conditional compile approach for handling embedded pointers for more than a few APIs, this approach and according bundling/unbundling from a proper LabVIEW cluster containing strings and arrays to a bitness specific cluster is going to be very ugly and almost impossible to maintain in the long run. There you have basically three options then:

 

+ create a wrapper DLL in C that translates these structures between LabVIEW friendly data and the DLL specific data. This is pretty much mandatory if the DLL has also callbacks that you want to translate into user events or some other mechanism that works with LabVIEW. Adding additional functions to handle friendly data type translation is then a pretty straightforward approach.

 

+ Use my memory manager library from vipm.io that I mentioned above to do the translation. Still quite a bit of manual work but it avoids the need to create an extra wrapper DLL at the cost of you playing C compiler yourself on the LabVIEW diagram.

 

+ Avoid the DLL altogether by implementing the functionality in LabVIEW. This might be impossible if you have no documentation about the communication protocol of a device and don't feel like reverse engineering it, or if the DLL implements proprietary algorithms that you are not allowed to implement yourself or don't have the information to do so. If it is about a device communication, especially if it is network based or serial port, this often is the more simple and much more maintainable approach in the long term and you can use it on every LabVIEW version/platform including LabVIEW realtime targets.

 

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
0 Kudos
Message 11 of 12
(116 Views)

Ah well that would explain why it's worked for me so far, I've been using Adapt to Type for all my clusters!  Thanks a ton, this is very helpful information!

0 Kudos
Message 12 of 12
(78 Views)