Debugging Shared Libraries and Calls to Shared Libraries
When you debug your LabVIEW calls to shared libraries, you must be prepared to trace problems in the shared library you are calling and in the implementation of the Call Library Function Node in LabVIEW.
Troubleshooting the Call Library Function Node
When the LabVIEW calls to shared libraries generate errors, check for the following problems in your use of the Call Library Function Node:
Verify the Call Library Function Node has the correct name or path for the shared library. Also ensure that you specify the location on disk appropriately for your use case. Some use cases require you to specify the shared library by path, and other use cases require you to specify the shared library by name.
If you receive the error message Function not found in library, verify the Call Library Function Node has the correct spelling, syntax, and case sensitivity for the function name that you are calling.
Be sure that the compiler has not decorated the function.
If you receive an error message that a secondary shared library cannot be found, yet you properly specified the path to the primary shared library in the Call Library Function Node, the primary shared library needs additional functions from one or more other shared libraries. You need to find the other shared libraries and place them in the same directory as the shared library that needs them or in a directory that is in the search path. Refer to the KnowledgeBase at ni.com for more information.
If your VI crashes, verify that return types and data types of arguments for functions in the Call Library Function Node exactly match the data types your function uses. Also, verify the Call Library Function Node uses the proper calling convention (C or __stdcall) using the Error Checking Level tab in the Call Library Function dialog box.
Verify that all the parameters are defined to be passed by the correct method, such as value or pointer. Also, verify the Call Library Function Node passes arguments to the function in the correct order.
For arrays or strings of data, always pass a buffer or array that is large enough to hold any results that the function places in the buffer. However, if you are passing them as LabVIEW handles, use LabVIEW Manager functions to resize them under Visual C++ or Xcode compilers.
If you receive a message, the cause is almost always an error in the code of the shared library, such as writing past the end of the memory allocated for an array. Notice that these kinds of crashes might or might not occur at the time the shared library call actually executes on the block diagram.
Use the Automation Open function with the Property Node and the Invoke Node instead of the Call Library Function Node if you want to call a shared library that contains ActiveX objects.
All calls to LabVIEW-built shared libraries should specify Run in any thread. If you configure the Call Library Function Node using LabVIEW-built shared libraries and specify Run in UI thread, LabVIEW might hang and require you to restart.
Pascal strings do not exceed 255 characters in length.
Resizing of arrays and strings can take place only when the Call Library Function Node passes a LabVIEW array handle or LabVIEW string handle. Resize arrays and strings using functions exported through labviewv.lib to a Visual C++ project, and liblvexports.a to an Xcode project
Remember that C strings are NULL terminated. If your DLL function returns numeric data in a binary string format, for example, through GPIB or the serial port, it might return NULL values as part of the data string.
Troubleshooting Your Shared Library
Check for the following problems in your shared library when LabVIEW calls to shared libraries generate errors:
Verify that shared library functions that other applications call appear in the module definition file EXPORTS section, or you include the _declspec (dllexport) keyword in the function declaration. Keep the C++ compiler from introducing platform dependence in exported function names through a process called name mangling by using the C++ compiler function export directive, extern "C"{}, in your header file, as shown in the following example code:
extern "C" {
/* your function prototypes here */
}
Remember that you need to declare the function with the _declspec (dllexport) keyword in the header file and the source code, or define it in the EXPORTS section of the module definition file.
When you use the _declspec (dllexport) keyword and you are also using the __stdcall calling convention, you must declare the shared library function name in the EXPORTS section of the module definition (.def) file. In the absence of a .def file, __stdcall might truncate function names in an unpredictable pattern, so the actual function name is unavailable to applications that call the shared library.
When a function has not been properly exported, you must recompile the shared library. Never recompile the shared library while the shared library is loaded into memory by another application, for example, by your VI. Before recompiling a shared library, make sure that all applications making use of the shared library are unloaded from memory. This ensures that the shared library itself is not loaded into memory during a recompile. The shared library might fail to rebuild correctly if you forget this point and your compiler does not warn you. However, most compilers warn you when the shared library is in use by an application.
Try to debug the shared library by using the source level debugger provided with your compiler. Using the debugger of your compiler, you can set breakpoints, step through your code, watch the values of the variables, and so on. Debugging using conventional tools can be extremely beneficial. Refer to the appropriate manual for your compiler for more information about debugging.
Calling the shared library from another C program is also another way to debug the shared library. By calling the shared library from another C program, you have a means of testing the shared library independent of LabVIEW, thus helping you to identify any problems, sooner.
When calling a LabVIEW shared library that passes a 2D array, you must first declare the handler variable and initialize the variable to NULL, as shown in the following C code:
main ( )
{
�������/*LabVIEW data handler variable for the array */
�������TD1Hd1myArray = NULL;
�������...
�������/* Call to the LabVIEW shared library function */
�������DLLFunctionalCall(&myArray);
�������...
}
If you do not initialize the handler variable to NULL, the code produces a General Protection Fault when you call the shared library.
To allow LabVIEW shared library functions to execute without interruption, LabVIEW delays the processing of operating system messages until the end of any calls to shared library functions or until you load a modal window from the shared library. Delaying the operating system messages, such as keyboard messages from the users, is useful in order to avoid calling the same shared library file while a shared library function runs. For example, if the shared library function is called in response to the user pressing a button, the user should not be able to press the button again until the shared library function has completed. When LabVIEW delays the processing of operating system messages, all function calls to the same LabVIEW shared library are put into a queue. That queue will be executed after the original shared library function call completes. A modal window is a type of window that remains active or remains on top of all other LabVIEW windows until you close the window or open another modal window. If you load a modal window from the shared library, LabVIEW overrides the process delay and processes the messages to allow the modal window to become active. You cannot interact with other windows while a modal window is open. Most dialog boxes in LabVIEW are modal windows. You cannot open a non-modal window from a LabVIEW callback VI nor a shared library while any other process is running. If you want your callback VI or shared library to call a non-modal window, you must do so programmatically by completing the steps outlined in the Callback VIs topic.
You can choose whether to delay operating system messages in shared libraries that you build. Before building the shared library, navigate to the Advanced page of the Shared Library Properties dialog box and remove the checkmark from the Delay operating system messages in shared library checkbox to process operating system messages while shared library functions run.
The following scenarios might cause the No debuggable applications or runtime libraries found error to appear.
The debuggable shared library was not loaded or was unloaded by the application.
The configuration (ini) file of the shared library, created by the Application Builder, was not distributed with the shared library.