From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Padding clusters to match C structures

I have developed a C library which runs on Windows, Linux, and NI ETS. I am in the process of developing a LabVIEW wrapper for the said library. Is there any way to configure the packing in the C library to be able to use one consistent structure in LabVIEW across all the operating systems and bit-sizes without modifying the C library?

 

I have read a KB on LabVIEW memory and how it is different on each operating system. Then found another KB which speaks about lining up clusters with structures. It says that the structure packing can be changed so the structure is aligned with the LabVIEW cluster.

 

I suppose I can construct some #ifdefs which will match the packing with the LabVIEW memory layout for each operating system. I prefer not to change my library to facilitate a wrapper as there is good chance I will wrapper the library in C# and perhaps other languages. Is there something I can do from the LabVIEW side? Is the best approach to create a case structure in LabVIEW and select the best structure to use for the OS?

 

0 Kudos
Message 1 of 16
(3,342 Views)

Use the two include files from the cintools directory around and structure type declaration that you use in the exported functions that you want to call through the Call Library Nodes as follows:

 

 

#include "platdefines.h"

......

#include "lv_prolog.h" typedef struct {     int32.t elm1; float64 elm2; ........ } whatever_struct; #include "lv_epilog.h"

lv_prolog.h sets up the packing according to the LabVIEW rules for the current platform you are compiling the shared library for.

 

lv_epilog.h resets the packing back to whatever the compiler used before the lv_prolog.h inclusion.

 

The alignments used by LabVIEW are different on different platforms. 32-bit x86 platforms tend to use byte packing, 64-bit x64 platforms use the default alignment, which is usually 8 byte. The PPC platform for some of the cRIOs has its own settings.

 

On MacOSX LabVIEW uses whatever is the default alignment for the compiler independent if it is 32 or 64 bit. Same on Linux but the standard GCC compiler doesn't know a consistent configuration to set the alignment to the natural default. Generally for all but MacOSX and Windows 32-bit compilation, changing in your project the alignment to anything but the default alignment will surely mess up your alignment of the structures for interfacing with LabVIEW.

Rolf Kalbermatter
My Blog
Message 2 of 16
(3,319 Views)

If you are the developer if this c dll then I suggest you provide functions to write/read parts of your structure, then only handle the structure in LabVIEW as an integer pointer passed between these functions.  Then details about packing never come up.

0 Kudos
Message 3 of 16
(3,282 Views)

@schddc wrote:

Is the best approach to create a case structure in LabVIEW and select the best structure to use for the OS?


Not a case structure, but a conditional disabled structure. Things like this is the purpose of the structure.

Message 4 of 16
(3,277 Views)

@drjdpowell wrote:

If you are the developer if this c dll then I suggest you provide functions to write/read parts of your structure, then only handle the structure in LabVIEW as an integer pointer passed between these functions.  Then details about packing never come up.


I want to add that I think that providing functions (that act on a pointer to a structure) is a better way to allow wrapping in any language.  It’s an object-like encapsulation; a simple public API.   I don’t write C dlls but I’ve wrapped a few, and the best ones (such as SQLite, that has been wrapped in many languages) don't expose raw structures.

Message 5 of 16
(3,270 Views)

@drjdpowell wrote:

@drjdpowell

I want to add that I think that providing functions (that act on a pointer to a structure) is a better way to allow wrapping in any language.  It’s an object-like encapsulation; a simple public API.   I don’t write C dlls but I’ve wrapped a few, and the best ones (such as SQLite, that has been wrapped in many languages) don't expose raw structures.


For DLLs (shared libraries) that you ever might want to interface to other environments too, this is definitely true! Python would come to mind as a possible environment, but Matlab just as much. Their interfacing to external libraries is similar with a scripting like approach that defines the parameter list of functions. While they allow to also describe structure datatypes in that way, it is cumbersome, error prone and generally quite a hassle to get right, and alignment issues between different platforms (yes Python can run on just about anything that has a C compiler available), would make the according definitions pretty convoluted if you intend to support more than one platform.

For a shared library that is only intended to be used by LabVIEW I would personally not hesitate to use the two earlier mentioned include files.

Rolf Kalbermatter
My Blog
0 Kudos
Message 6 of 16
(3,259 Views)

@rolfk wrote:

@drjdpowell

For DLLs (shared libraries) that you ever might want to interface to other environments too, this is definitely true!


That is what the OP is trying to do; make a common dll callable from many environments without modification.   In my SQLite wrap, I used the pre-compiled dll from the SQLite website, which is made by developers that may never have even heard of LabVIEW, and it worked fine.

0 Kudos
Message 7 of 16
(3,249 Views)

@drjdpowell wrote:

@rolfk wrote:

@drjdpowell

For DLLs (shared libraries) that you ever might want to interface to other environments too, this is definitely true!


That is what the OP is trying to do; make a common dll callable from many environments without modification.   In my SQLite wrap, I used the pre-compiled dll from the SQLite website, which is made by developers that may never have even heard of LabVIEW, and it worked fine.


Correct. I'm trying to make a common dll without custom modifications specifically for LabVIEW. I already have a wrapper for C# with works if I have to recompile the dll with new packing then it would require me to change the C# wrapper which is unpleasant.

I'm really trying to understand the best way to handle this internal to my LabVIEW VIs. Since I will be using and supporting LabVIEW on at least Win 32, Win 64, and NI ETS I have to worry about the different packings used on the different systems.

Currently, I have multiple variants of my structure with different padding and one variant of the structure with no padding. I use a conditional disable structure (not case structure thanks ) to select the appropriate structure to use for the CLN. I then map the OS padded structure to the no padding structure. I was hoping there was a better way to do this.

0 Kudos
Message 8 of 16
(3,199 Views)

@drjdpowell wrote:

@rolfk

That is what the OP is trying to do; make a common dll callable from many environments without modification.   In my SQLite wrap, I used the pre-compiled dll from the SQLite website, which is made by developers that may never have even heard of LabVIEW, and it worked fine.


I think it is debatable if he really wanted to call this DLL from other environments than LabVIEW. Especially the mentioning of NI Pharlap ETS would indicate that it is mainly a LabVIEW RIO solution, (Linux probably too for the Linux based RIO devices), and then of course LabVIEW for Windows for the development environment (the only platform you can really develop NI RIO applications on). 

Rolf Kalbermatter
My Blog
0 Kudos
Message 9 of 16
(3,234 Views)

@drjdpowell wrote:

@rolfk wrote:

@drjdpowell

For DLLs (shared libraries) that you ever might want to interface to other environments too, this is definitely true!


That is what the OP is trying to do; make a common dll callable from many environments without modification.   In my SQLite wrap, I used the pre-compiled dll from the SQLite website, which is made by developers that may never have even heard of LabVIEW, and it worked fine.


Correct. I'm trying to make a common dll without custom modifications specifically for LabVIEW. I already have a wrapper for C# with works if I have to recompile the dll with new packing then it would require me to change the C# wrapper which is unpleasant.

The tip about including the labVIEW header files was great but I don't think it's what I'm looking for. I have seen them used before but didn't understand what they did. So it was helpful to get an explanation of them. Now I have them in my toolbelt for the future.

I'm really trying to understand the best way to handle this internal to my LabVIEW VIs. Since I will be using and supporting LabVIEW on at least Win 32, Win 64, and NI ETS I have to worry about the different packings used on the different systems.

Currently, I have multiple variants of my structure with different padding and one variant of the structure with no padding. I use a conditional disable structure (not case structure thanks wiebe@CARYA) to select the appropriate structure to use for the CLN. I then map the OS padded structure to the no padding structure. I was hoping there was a better way to do this.

0 Kudos
Message 10 of 16
(3,225 Views)