LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Trying to Follow White Paper - Running a LabVIEW Application on Linux Without a Graphical User Interface

Solved!
Go to solution

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

 

When I try to compile I get an error that 

 

In file included from test.c:1:0 

test.h :1:21: fatal error: extcode.h: no such file or directory

 

Where test.h is the header built by the LabVIEW Build Process from the Project.

 

In that file there is the line for 

#include extcode.h

 

extcode.h does in fact exist on my system.  I feel like I am missing a "link" or "include" command somehow on the instructions for compiling the C code to be executable.

 

gcc <options> -o FILENAME test.c ./SharedLibFromVI.so -L <path to RTE>

 

Note: this is Cent OS 7.6 with gcc compiler 4.8.5 if this helps at all.  LabVIEW 2018 SP1

 

extcode.h is located at: /usr/local/natinst/LabVIEW-2018-64/cintool/extcode.h

 

Anyone have a hint on how to get the compiler to find the extcode.h?  In case you can't tell I do not usually write and compile C code.

Ryan Vallieu CLA, CLED
Senior Systems Analyst II
NASA Ames Research Center
0 Kudos
Message 1 of 25
(1,953 Views)

Thank you, that worked.

 

Just had to fix the spacing issue on the linked page for the -I <include path> and it compiled fine.

 

I appreciate it.

 

Now I have a couple .so created and C files and am calling LV code from C executables.

 

Interesting that the LabVIEW Code called this way doesn't seem to share the same LabVIEW Application Space.

Ryan Vallieu CLA, CLED
Senior Systems Analyst II
NASA Ames Research Center
0 Kudos
Message 3 of 25
(1,880 Views)

@RVallieu wrote:

Interesting that the LabVIEW Code called this way doesn't seem to share the same LabVIEW Application Space.


Each process gets it's own application space. Two LV executables can't communicate over LabVIEW queues, events, globals, etc..

 

You'd have to use a OS global resource or communication, like memory mapped files, OS named queues, shared variables, TCP\IP, or plain files. 

Message 4 of 25
(1,837 Views)

Shoot, I was hoping that since there was one LabVIEW run-time Engine and I turned off “Execute VIs in private execution system” and another post I read seemed to indicate that they would share the same app space that it would work that way.  

 

I had posted this very question, so thank you for the answer.  Hmmm.  Not impossible now to do what I want, just more planning and coding is needed I think.

https://forums.ni.com/t5/Linux-Users/LabVIEW-VIs-called-from-SO-application-space/gpm-p/4086074

Ryan Vallieu CLA, CLED
Senior Systems Analyst II
NASA Ames Research Center
0 Kudos
Message 5 of 25
(1,819 Views)
Solution
Accepted by RVallieu

@RVallieu wrote:

Shoot, I was hoping that since there was one LabVIEW run-time Engine and I turned off “Execute VIs in private execution system” and another post I read seemed to indicate that they would share the same app space that it would work that way.  


If you have a LV dll and call it from LabVIEW, they will use the same run time engine. If that option is on, the dll and the executable will use the same execution system.

 

The LV run time engine is pretty much exactly like the C\C++ run time.  

0 Kudos
Message 6 of 25
(1,815 Views)

OK - so I have ONE C executable - in it I am launching a LabVIEW Main that runs in a while loop.  I am launching that dynamically, not waiting for execution complete.  In the same C code I am running an Enqueue function to pass an Integer to the Main that has created the Named Queue to receive the Integer from the Enqueue VI that the C code will try to pass into it via the Enqueue VI that gets the same named Queue as the Main.

This does not seem to be working to pass information to the Main.

 

Excuse my psuedo code

 

C Main 

{

   launch Main_dynamically (this seems to be working);

 

For Loop (count=0, count<5, count++) {

   Enqueue(count); 

   }

 

//to keep the C code alive - I check that the LabVIEW code is still running.

   do {

       running=checkLVMainRunning()

        } while(running=1)

 

return 0; 

}

 

Should I be able to utilize the Q with VIs that are all inside the same .SO to use named Queues for C to call and pass information between the Enqueue and Main?

Ryan Vallieu CLA, CLED
Senior Systems Analyst II
NASA Ames Research Center
0 Kudos
Message 7 of 25
(1,742 Views)

@RVallieu wrote:

Should I be able to utilize the Q with VIs that are all inside the same .SO to use named Queues for C to call and pass information between the Enqueue and Main?


There are very few people that know things like this, even fewer that ever tried that... I sure didn't.

 

I'd first try to make this work in LabVIEW. First simply calling VIs, then make a dll and call the functions from LabVIEW. If it doesn't work in LabVIEW, it will never work outside of LabVIEW. That will also iron out all problems with the code. You might already have done that of course.

 

I'm not sure how the dll is loaded in C. Can you be sure the dll is loaded once, and then stays in memory for the 2nd call? C could make the first call, thinking it's done releasing the dll, and then load and make the 2nd call. I don't know, but I'd try to make sure (not sure how). You could try to use LoadLibrary to load the dll, and calls will use the loaded module if it's in memory, until you release it (I think).

0 Kudos
Message 8 of 25
(1,720 Views)

Application contexts can be a problem when you try to do things like this. Inside LabVIEW things are pretty easy as it takes care about almost everything for you.

 

An application context is any target in your project file. For each such target, LabVIEW manages the according context automatically for you and opens VIs in their respective context based from where in the project you opened them. LabVEW also knows its own internal contexts in which it runs for instance the application builder or all the tools that you can select in the Tools menu. This makes sure that these tools can not inadvertly interfere with your VIs in your project even if they might use internally VIs with exactly the same name as are present in your project. It also requires you to jump through a few hoops if you want to access something in your project from one of these tools, as you will have to find the application context that belongs to the place in your project you want to modify something in, and then pass that to according functions that accept such a context as input. By default these functions always assume the current context of the code that they are running in.

 

Now lets switch to DLLs (or shared libraries). There is your main() process from your C program. It knows absolutely nothing about LabVIEW and accordingly its application contexts. All it cares about are the code it contains from your C code and the references to external functions contained in a multitude of shared libraries (pretty much every function you call in your C code is in reality located in some shared library somewhere). When it first encounters a call to one of your LabVIEW shared library functions it simply requests the dynamic loader to load that library. This in turn causes the shared library initializer to be called and here things get rather complicated. This initializer will locate the lvrt shared library, which in fact is the whole LabVIEW runtime as contained in your LabVIEW development system sans almost all functions that are related to modifying and saving LabVIEW code, displaying diagrams, compiling LabVIEW code and such things. Here the lvrt runtime will basically initialize a complete LabVIEW environment and that involves almost everything that is also done when starting LabVIEW itself. It is here were threads are spun up that will interact with the OS GUI system and these are kept alive for the entire lifetime of the lvrt runtime. This is the main reason that running LabVIEW executables and even shared libraries in a completely headless environment is such a challenge. And this code is deeply intervoven in the core of LabVIEW so that just janking it out is a pretty much impossible thing. They had to work on that when developing LabVIEW realtime for CompactRIO and similar targets since most of them simply have no display at all, but it was not trivial and it was not in a way that removed this dependency completely as that would have required a complete rewrite of LabVIEW from ground up.

 

Anything refnum based in LabVIEW is application context specific since these refnums are managed on a context base. A refnum opened in one context means totally nothing to a VI function running in another context. As refnums are really just integer identifiers there is a very very tiny chance that one refnum from one context may seem to represent a valid refnum in another context, but they are in fact two completely different objects. Generally however a refnum from a different context will simply cause the according function to return an error 1, invalid argument, since it could not resolve that refnum to a valid object.

 

So one thing you can do in your bug hunting here is to actually use proper error handling and also return those errors in the functions that you call in your LabVIEW library. You do want to get as much information as possible when doing such complicated setups and proper error handling is the most basic step for this. Otherwise you can keep stabbing into the dark all the time you want, but you will never arrive at any conclusive answers.

 

And pseudo code can help sometimes, but if you want others to really help you with such complicated issues, you should take the time to actually build a simple example that demonstrates the issue you have perfectly and then ZIP it up and attach it here. We are not asking you to send any state secrets here, just a simple example that people here can build and run on their own system. Even if someone does this on his Windows machine instead of on Linux it will give more actual info than just starting to speculate about possibly complications of LabVIEW application contexts in shared libraries.

Rolf Kalbermatter
My Blog
Message 9 of 25
(1,714 Views)

Obviously LoadLibrary won't work on Linux.

 

Is there a Linux equivalent?

0 Kudos
Message 10 of 25
(1,706 Views)