LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Latest version of the 'Using External Code in LabVIEW' Manual?

Solved!
Go to solution

Having problems finding detailed information about building a DLL with the Call Library Function Node. I did a bunch of external code with the Code Interface Node (now extinct) and there was a manual "LabVIEW Code Interface Reference Manual" with the build instructions. I can't find anything similar for the newer Call Library interface. I have a bunch of notes on how to do it with the CIN, but obviously things have changed. You used to need a "CIN MgErr CINRun" function, but I don't see that in the generated .c file.

I am using Visual Studio C++ 2010 and the build steps obviously have changed.

For example, there is no "lbsbmain.def" file in cintools. There used to be a custom build step, but I am not sure if it is the same any more:

Command Line = "<cintools>\lvsbutil" "$(TargetName)" -d "$(ProjectDir)$(OutDir)"
Outputs = $(OutDir)$(TargetName).lsb

 

Can anyone point me to real documentation? All LabVIEW help talks about configuring the Call Library Node, but that is easy.

0 Kudos
Message 11 of 16
(767 Views)

There is nothing special about creating a LabVIEW specific DLL. Use whatever C compiler environment you want to use that can create DLLs and use the necessary project settings to create a DLL target. If you want to use LabVIEW Manager functions in your DLL there are a few rules you need to follow:

 

- #include "extcode.h" must be added to the top of your C source file so that the C compiler can know what LabVIEW manager functions and datatypes your code can use

- you need to link the resulting object files with the additional labview.lib or labviewv.lib from the cintools directory

 

This last step requires that your C compiler can deal with Microsoft COFF libraries. Microsoft compilers obviously can, and so can modern GCC versions included for instance in MingW.

 

That's it. There is no other magic.

 

The External Coder Reference Manual is still largely relevant to document what LabVIEW manager functions you can call and how their function prototype looks and what parameters those functions have. You simply can ignore anything about how to create CINs because that is not necessary anymore.

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

I appreciate your quick reply. So, we are just making a generic DLL now instead of the proprietary .LSB file.

 

There is a NI link that says you need a DllMain function (never required with CINs). Is this correct?

https://knowledge.ni.com/KnowledgeArticleDetails?id=kA03q000000x1OvCAI&l=en-US

 

If I make an empty project (without the DllMain function), will it still work with LV?

There is also a discussion about using:

extern "C"

But, I assume this is unnecessary if I use calling convention __cdecl (compile as C code)?

 

There is also a discussion about exporting functions (never required with CINs):

extern "C" __declspec(dllexport) ...

Is this required?

 

Is there an actual LabVIEW reference document or help file that discusses these details?

 

0 Kudos
Message 13 of 16
(722 Views)

You are asking a lot of questions that are basically all completely non-LabVIEW related but standard C "knowledge".

 

The DLLMain() function is the function mandated by Microsoft for DLLs, similar to your main() function for standard C executables. Newer Microsoft compilers may substitute with a default DLLMain() function if the project target is for a DLL and there is non found in the project modules.

 

extern "C" is mainly a keyword that tells a C++ compiler to treat the according declaration block as a standard C declaration. This mainly avoids so called name mangling of function names if you happen to invoke the C++ compiler instead of the C compiler. For Microsoft builds invoked through make or the Visual Studio IDE, this is for instance automatically determined based on the source code module file name ending (but can be explicitly overwritten through the project settings for the according module file). So if you compile a .cpp file that includes headers that define symbols without extern "C" declaration, the compiler will assume that those symbols are name mangled and then you get linker errors if you try to link this object file with the actual object module for that function implementation when it was compiled as standard C code, since the exported symbol name does not match what your module tries to import.

 

So extern "C" is not about __cdecl or __stdcall, which under non Microsoft Windows 32-bit compilation anyhow doesn't really exist (yes Windows 64-bit does not use __stdcall either) but about the difference between C and C++ compilation.

 

The calling convention is of course important. Caller and Callee need to agree about that. Typically the compiler assumes a default calling convention (usually __cdecl for 32-bit compilation, __fastcall for Windows 64-bit). This can be overwritten by a switch in your project file, and that can again be overwritten by an explicit calling convention declaration in the function prototype declaration in the header file. Generally it is a good idea to define that explicitly as it avoids ambiguities caused by different project files for the DLL compilation and the users of such a DLL. But it also adds extra complexity if you develop for multiple platforms since these calling conventions are often rather platform specific, so you shouldn't just use the calling convention statements verbatim but rather through conditional defines that resolve to different values depending on the current platform target.

 

__declspec(dllexport) or __declspec(dllimport) determines if the compiler puts the according function in the DLL export table, or tries to link it to a symbol in the DLL import table. If your source code does not implement the according function you would get a linking error for a dllexport symbol since the linker requires an actual implementation to link to the export table entry. On the other hand if you declare a symbol as dllimport but your code implements an according function too, you get an error too, since the linker doesn't know if it should use the locally defined symbol or the one from the import table. This is Microsoft specific. If your code should compile for other platforms too, you should again use conditional defines and declare them for GCC builds for instance to the according attribute() definitions.

 

All in all, non of the points you mention has anything to do with LabVIEW specifically, but are simply things you need to be aware of when developing DLLs. And since use of LabVIEW is not about developing DLLs but at most about using them, non of this information is specifically suitable to any of the LabVIEW manuals. It's all documented on the Microsoft Website, where it really belongs on, in one way or the other, but yes, good luck in finding it if you do not know what exact keyword to look for, and even then it can be difficult. But you are of course welcome to document your findings and post them here as a concise manual. 😁

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
Message 14 of 16
(710 Views)

Thanks for your detailed explanations, Rolf.

I am asking about the DLL build process because many things have changed from CIN development and there is no documentation to really explain if there is anything LabVIEW specific (like there used to be for CINs). Maybe this would have been easier if I wasn't expecting the extra steps (like setting Struct Member Alignment, etc.).

I had to switch over to Visual Studio Community 2022 to get the x64 compiling which I didn't have in my old 2010 version.

It's still not clear to me if I need the dllmain function or export [__declspec(dllexport)] for LabVIEW, but I put them in to be safe.

 

Good news is that I have built a DLL that is working with the Call Library Function Node, so your explanations helped get me here. 😉

 

0 Kudos
Message 15 of 16
(682 Views)

I still use sometimes Visual Studio Professional 2005 SP1 for generation of both 32-bit and 64-bit executables and DLLs. It’s the first Microsoft Visual C version to fully support 64-bit compilation.

But it has to be the licensed version with all the patches that were ever released and installation under Windows 10 only succeeded once.

 

Visual Studio 2015 was the first providing a Community version with similar feature set than the Professional version. Prior to that you only had Express versions which were severely limited in comparison to the Professional version and that resulted in many features being unsupported, including 64-bit compilation.

 

Specific struct member alignment is mandatory for CINs so it was included in the special build setup for CINs. It is optional for DLLs because it is only required for clusters you want to pass directly from the LabVIEW diagram to the DLL or back. Any other structs in your C code should use whatever alignment the respective API requires. And by now only the LabVIEW for Windows 32-bit version uses non default alignment. All others use the platform default alignment. The reason is that the Windows 32-bit memory model that LabVIEW is still using was introduced back in 1992 with the release of LabVIEW 2.5. At that time many users were still running their Windows system on machines with 4 MB of physical RAM!!!! 8 MB of RAM was considered an excessive amount by many and cost you an arm and a leg. By byte packing structures, LabVIEW could squeeze out a little more of memory and the x86 architecture contains quite a bit of extra transistors to try to avoid a performance hit when accessing unaligned memory addresses, so it was considered a good trick in those days.

Multiplatform C development was at that time still something almost unheard of and every platform had their own compiler, rules and defaults anyhow. In fact, every compiler had their own rules even under the same platform.

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