09-24-2020 05:34 PM
I am following https://knowledge.ni.com/KnowledgeArticleDetails?id=kA00Z0000019RYlSAM&l=en-US trying out calling LabVIEW Code wrapped in .SO from C code that I build into EXE using the GCC compiler on my Cent OS 7.6 PXIe-8135 system. LabVIEW is 2018 SP1.
I got the .SO building working. I have the GCC compiler creating the C exe code. I can create and write to files to verify that my LabVIEW called from C code is working. I can see in Linux using TOP that my Code is running.
Once I verified with a simple VI to create and write to a file I then tried is writing a Notifier Sender using a Named Notifier, and a Notifier Receiver using the same Named Notifier. Then I also created a Functional Global to store a Stop Flag that both VIs read. My point of this was to see if the LabVIEW code called by the C code out of the .SO, but all using the headless LabVIEW Runtime Engine option would all be run in the same LabVIEW Application Space, and thus could all access the same Functional Globals, Named Notifiers, Named Queues, DVRs, etc. What I think I am seeing is that they are not all running in the same application space under LabVIEW runtime.
My Notifier Broadcast – runs in a While Loop, writes out on a Notifier every 1 second the value of the Iteration terminal.
My Notifier Receiver – runs in a While Loop, reads using the attempts to grab the Notifier Ref by name, then Wait on Notification to get the Broadcast value of the Iteration and writes to a text file so I can verify the transmission is working.
I have the Stop Functional Global VI set to Write True when called from a C code exe as well.
I can see in TOP that both VIs are running.
Results making me think they are not in the same application space:
Calling the Write Stop FG C Code does not stop the Broadcaster or Notifier.
The Notifier Receiver is creating the text file where it is supposed to write the received Iteration, but if it does not get the Notifier Reference (create is set to F) then it keeps waiting for it until Stop = T or it gets the reference on another iteration. It is not writing the Iteration Value to file, thus I know it is stuck in the "attain ref." part of the code.
Is this expected behavior? Is there a way to open a VI in this manner from C code and have all the VIs in the same LabVIEW "Application Space"?
I did see the check box in the Shared Library Properties for “Execute VIs in private execution system” - I turned that off thinking that would allow all the VIs in the .SO to run in the same LabVIEW Run-Time Engine and thus access the Named Notifiers, Named Queues, DVRs, etc. as if they were running in the LVDEV environment, or a single LabVIEW EXE.
I understand I can write a "top level" VI that calls the lower level VIs and include that in a .SO - but I was hoping to leverage C code to and launch LabVIEW VIs and have the LV VIs be able to access the same LabVIEW application space.
Is this not possible?
Solved! Go to Solution.
11-05-2021 11:31 AM
Hmm. Running into this issue again now that I am trying to go from LabVIEW EXE to running the code from a .SO and Embedded LabVIEW Run-time.
I'd think that if a VI called from within the .SO then dynamically launched another VI from disk they would all be in the same application space. I'll try to add some extra debugging. Of course this all works in the regular EXE.
11-05-2021 06:36 PM
Well I am able to launch the dynamic VIs and pass them Q references. These references work fine. I couldn't create the references by name in the Dynamically launched VIs.
Now the issue I am having is the dynamic VIs loaded from the Source Distribution Folder dont seem to be able to convert a TCP message properly.
I'm wondering if the static subVI on the block diagram of the Dynamic VI is not loading or something strange. The TCP connection passed in via the Queue is passing proper number of bytes but my sub VI uses some typedefs in a polymorphic VI to convert I32 numbers to Enums for ease of use in the code. i.e. convert I32 "6" to Enum: Ping (6). It's not a straight mapping though since the incoming numbers can be negative, I recreated value/string pairs with a Ring Typedef and then convert that via string name matching on the Enum for the Enum index selection.
I'm not getting any conversion or load errors....this is odd. This TCP connection and conversion works in the regular LabVIEW EXE version where it calls the Instrument VIs dynamically. Hmm
11-08-2021 12:44 PM
AHA! and DERP at the same time.
The lowest level VI in the conversion is using front panel object properties for the Ring and Enum to get [STRINGS] and [STRINGS AND VALUES] at the first run of the VI.
Because it is embedded - there is not a front panel.
The VI fails to convert the incoming numeric to the Enum because the Arrays generated without the front panel are empty.
Should have thought of this sooner.
The bad thing is in the Build Spec for the VI in the Library, I can not turn off Remove Front Panel - that whole field is turned off.
11-08-2021 03:09 PM
Well now I fixed that - the conversion is working properly from I32 to Enum using the Rings and Strings...
But now I am finding my Dynamically loaded VIs can not access Hardware Drivers seemingly?!?!
I have a DAQmx Task property node for AutoZero for a PXIe-4309 card and also had a GPIB instrument Property Node that extracted Primary Address...these are not Front Panel Property nodes
Both of these are now failing and throwing errors - acting like the dynamic VIs can not access the Device Drivers.
11-08-2021 04:39 PM
Ah - DAQmx ZI.AutoZeroMode setting is a Ring and I was using a property node to access it and pick the correct value based on the String entry of the Hardware config. Replaced that Front Panel property node and the DAQmx driver access in the Dynamic VI is working.
Now to figure out why the VISA Instr property node is throwing an error from the other Dynamic VI.
11-08-2021 05:03 PM - edited 11-08-2021 05:04 PM
Upstream front panel property node.
Went through the code with the search for Property nodes and replaced all the calls I could with other methods.
instruments are now working.
Shame that Rings can not get access to the Strings and Values without a Front Panel Property Node like you can with the Enum and Flatten to XML.