As LabVIEW developers, we are comfortable developing in LabVIEW. However, sometimes we need to leverage code from other languages. This is where DLLs come in. For those of us that are less than comfortable with coding languages outside of LabVIEW, using DLLs can be daunting and frustrating. The Import Shared Library Wizard can make your life easier, however, it is not very reliable when using custom data types. This forces us to use Call Library Function nodes (CLNs) for DLL calls, which can bring up a whole bunch of problems with no intuitive debug strategy.
When you are caught up in the midst of 1097 errors and unknown LabVIEW crashes, a clear debugging strategy is extremely helpful. In my recent experience using DLLs I have found four crucial practices that will hopefully make your experiences with DLLs slightly less frustrating.
- You MUST have the source code.
Hopefully this is an obvious one for most of you. If not, I CANNOT stress this enough. You will HAVE TO leverage the source code to properly configure your CLNs. If you are building LabVIEW code from scratch it is virtually impossible to configure a call library node without knowledge of the function prototype in the DLL’s header file.
In my case, however, I was given code with some pre-configured CLNs and .dll files with no source code. Debugging in the scenario becomes an actual nightmare. In this case, do your best to track down the source code because it will be essential for my next two tips.
- Calling conventions cause labVIEW crashes.
After looking at the source code and configuring the parameters of your CLN, you may run your code only to find it crashes LabVIEW instantly. One of the most likely causes of a LabVIEW crash from a CLN is an incorrectly defined calling convention. The default calling convention is C, but most CLNs should be configured to stdcall (WINAPI). If you are unsure which calling convention to use I suggest trying this one first. Then, if it does in fact cause a LabVIEW crash (sorry!), change the calling convention to C. Most of the time you should know what language the code was written in and you should be able to make an educated choice.
- Initialize sizes of EVERYTHING.
Especially when using arrays, or arrays within clusters, or arrays within clusters within arrays (…you get the idea), it is imperative that you know the sizes of ALL of your arrays. If you are getting a 1097 error from your CLN, it is likely because the data types were not defined correctly. This is where leveraging the source code comes in handy. When array sizes are not defined correctly, it can cause memory leaks. This can cause 1097 errors, crash LabVIEW, or give a warning when you close LabVIEW.
Part of this is defining the parameters properly in the CLN and part of it is initializing the parameters properly on the block diagram. The data type and size of each parameter is defined somewhere in the source code. Once you have located this information it is important to initialize the sizes of arrays and pass that information into the CLN. The less LabVIEW crashes you have to deal with, the happier you will be!
- Error Checking levels can hide errors.
The last tip I have for you when configuring CLNs, is to make sure you are not ignoring errors. The error checking tab in CLN configuration allows you to set the level of error checking within the CLN.
You may want to optimize your code by disabling error checking, which is completely fine. However, I recommend that you run your code with a minimum of a default error checking level during development. If you have disabled error checking during the development process, you will be blissfully unaware of things like 1097 errors and memory leaks. This is not as good as it sounds and will come back to bite you if left unchecked.
Once you have confirmed that the DLL call works properly, you can change the configuration back to disabled error checking to optimize your code.
Hopefully these tips save you some headaches while trying to develop with DLLs in LabVIEW.