05-13-2015 09:51 AM
it seems unnecessary with other NI technologies like static VI references, and packed project libraries (which also have issues).
Well, I need to work with an EXE <--> ADDON architecture, so static refs don't help.
The PPL looks promising, what "issues" are you referring to?
I've never used LVLIBs or PPLs, but Sam's idea has brought me into the 21st century...
Blog for (mostly LabVIEW) programmers: Tips And Tricks
05-13-2015 10:17 AM
Haha, my pleasure! 🙂
To answer some of your questions (to save you the pain of going through what I and many others have had to go through!):
QUESTION: Does a PPL work OK with a LabVIEW EXE? In other words, if the host is compiled into an EXE, can I plug in a PPL and have it work?
ANSWER: Yes
QUESTION: Can I have a COMPLICATED CALCULATION vi in the host, and have PPL#1 use it, and have PPL#2 use it, without conflicts? (I assume that if I change the calculation, I would have to rebuild the host and the two PPLs).
ANSWER: In this case, what would probably happen is that both of the PPLs will pull in their own copy of the COMPLICATED CALCULATION vi. If you changed COMPLICATED CALCULATION.vi - you would need to rebuild both PPLs for the changes to get incorporated.
QUESTION: If I move the PPL from PROJECT \ MYPPL.ppl to PROJECT \ SOME FOLDER \ MYPPL.ppl, without recompiling anything, and point the host to it , does it still work?
ANSWER: Yes
QUESTION: Do ALL functions work across the fence? Can I pass in a Notifier RefNum (as I do now) and then pass notifications and have them received in the PPL?
ANSWER: This is the biggest area where you are likely to have issues. When you load a VI from a PPL, it is loaded in the same application instance as your EXE so that means that any references (e.g. queues, notifiers etc.) are valid in both the PPL and the executable (e.g. you can wire a queue into the PPL VI and enqueue/dequeue etc.). HOWEVER (and it's a BIG however), any VIs in the PPL are contained in their own namespace - this means that if your queue is based on a type definition, the typedef inside the exe will be namespaced differently to the one in the PPL. This is where I have fallen over before with PPLs. It also means that FGVs don't work as you might expect (your PPL VI will call it's own version of the FGV). There's lots of information out there about this on the NI community - there was an excellent presentation all about PPLs at the CLA-E summit (I have attached it!) along with other articles/pages about PPLs.
QUESTION: Can the PPL have a user interface (visible panel)?
ANSWER: Yes.
QUESTION: Can I insert such a beast into a SubPanel on the host, and have it work normally?
ANSWER: Yes.
QUESTION: Can I obtain properties (such as FrontPanel.PanelBounds) from the main VI in a PPL? I use that to size the containing window.
ANSWER: Yes.
05-13-2015 10:41 AM
ANSWER: In this case, what would probably happen is that both of the PPLs will pull in their own copy of the COMPLICATED CALCULATION vi. If you changed COMPLICATED CALCULATION.vi - you would need to rebuild both PPLs for the changes to get incorporated.
OK, that's exactly what I WANT to happen. It can use the same CTL\VI as in the host, but it doesn't actually have to LINK back to that. It is self-contained.
Of course that has its own issues: I can't use a functional-global type of VI (which I use sometimes), and I can't share global variables (which I don't do anyway, except as constants), but that's OK. Yes, it's a bit space-inefficient, but that's a small concern compared to the fragility.
Blog for (mostly LabVIEW) programmers: Tips And Tricks
05-13-2015 10:52 AM
QUESTION: Do ALL functions work across the fence? Can I pass in a Notifier RefNum (as I do now) and then pass notifications and have them received in the PPL?
ANSWER: This is the biggest area where you are likely to have issues. When you load a VI from a PPL, it is loaded in the same application instance as your EXE so that means that any references (e.g. queues, notifiers etc.) are valid in both the PPL and the executable (e.g. you can wire a queue into the PPL VI and enqueue/dequeue etc.). HOWEVER (and it's a BIG however), any VIs in the PPL are contained in their own namespace - this means that if your queue is based on a type definition, the typedef inside the exe will be namespaced differently to the one in the PPL. This is where I have fallen over before with PPLs. It also means that FGVs don't work as you might expect (your PPL VI will call it's own version of the FGV). There's lots of information out there about this on the NI community - there was an excellent presentation all about PPLs at the CLA-E summit (I have attached it!) along with other articles/pages about PPLs.
OK, I can understand that. It looks like if I want to have PPL 1 and PPL 2, then I have to have LVLIB 1 and LVLIB 2. And if I do that, and have a typedef called MYCLUSTER, then in reality the host has a MYCLUSTER.ctl, and the PPL1 has a MYLVLIB1.MYCLUSTER.ctl, and the PPL2 has a MYLVLIB2.MYCLUSTER.ctl.
so, it's possible (probable?) that the types will mismatch and somebody will complain.
I will run into that, as I have an analysis results record that is just such a typedef, and I need to share it around. I guess I can flatten\unflatten to get across the fence.
I should just make a habit of flattening\unflattening at the border for such things.
I'm already using STRINGS in the notifier, rather than my more customary typdefed ENUMs, just for simplicity.
And the FGV issue I had already realized. Those are not shareable.
Thanks!
Blog for (mostly LabVIEW) programmers: Tips And Tricks
05-13-2015 11:13 AM
QUESTION: Can the PPL have a user interface (visible panel)?
--- Confirmed - YES!
QUESTION: Can I insert such a beast into a SubPanel on the host, and have it work normally?
--- Confirmed - YES!
QUESTION: Can I obtain properties (such as FrontPanel.PanelBounds) from the main VI in a PPL? I use that to size the containing window.
--- Confirmed - YES!
Blog for (mostly LabVIEW) programmers: Tips And Tricks
05-13-2015 11:16 AM - edited 05-13-2015 11:18 AM
Yeah, there are a couple of workarounds/solutions to the namespacing issue:
1) Flatten type-def'd things to variants before passing them into the VI and then convert them back inside the PPL - that should work.
2) Put any FGVs / type-definitions in their OWN PPL and have both the executable and PPL call those versions instead of their own version. That way both will be calling the version from the same namespace (i.e. the one inside the PPL) - you just have to be careful that you drop the version from inside the compiled PPL onto your block diagram instead of the source version.
05-13-2015 11:29 AM
Thanks for that PDF, I think. But they're using Double-Density Printing, apparently:
Blog for (mostly LabVIEW) programmers: Tips And Tricks
05-13-2015 11:50 AM
I've put the original in a zip file - the forums wouldn't let me upload a .pptx so I figured saving as a PDF would be the most convenient/quick way to post it here. Unfortunately the presentation was posted within the CLA group on the NI community so not everyone has access.
I can't take any credit for the content - but it was a useful presentation (Thanks Jarobit - in case you see this!).
05-13-2015 12:04 PM
It's still gorched.
I can't open it in WIndows (don't have Office), but it opens fine in KeyNote.
But the double-density printing is still there,
Don't worry about it though. I've found enough material to get me going.
Thanks to you !
Blog for (mostly LabVIEW) programmers: Tips And Tricks
05-13-2015 12:14 PM
@CoastalMaineBird wrote:
This is the big hurdle. None of this answers why the wizard is such a turkey, but I don't care.
The wizard isn't a "turkey," you're expecting it to do the impossible. A C header provides only the information the compiler needs, not the information the programmer needs. The most common example is passing an array versus passing a scalar by reference. These are both described identically in a C function prototype, because the compiler only needs to know that it's passing a pointer. The programmer, however, needs to know (through documentation or other non-code information) whether it's a scalar or an array. Another example, as you're seeing here, is that "int" is not required to be a specific number of bits.
So, when LabVIEW creates a header file, it has to make a choice: use custom data types (such as int32_t) to make it absolutely clear what data type the function expects, or substitute "int" and hope that the C compiler happens to agree on the definition of an int (as one example; arrays are another problem). NI chose the former approach. Unfortunately, the reliable way of defining an integer of a specific size involves including system header files, where such things are defined. It's looking for OS X headers on a Windows box because your normal Windows C compiler would define several pre-processor constants that would tell it that it's running on Windows, but the shared library import wizard (which is not a full C pre-processor, never mind a full C compiler) does not.
In some ways a LabVIEW-generated header file is the worst case for the shared library import wizard, because the LabVIEW DLL builder does all sorts of things to make sure that a C compiler will not misinterpret how to pass data to the LabVIEW functions across different platforms, whereas the shared library wizard expects to import headers that were built entirely with standard C data types for the specific platform on which it's running.
I suspect you can get the notifiers to work by typecasting to a U32, but it would be dangerous. As I understand it (and from reading RolfK's posts), LabVIEW does something special when it determines that it is loading a LabVIEW-built DLL from the same run-time version. In that specific case, it loads the DLL's VIs into the same application instance as the calling VI (with maybe some namespacing to avoid conflicts), so the notifier might work. However, if the DLL and calling VI are running in different versions of LabVIEW, then it won't work.
By the way, about namespacing - I don't understand the type definition problem. Wouldn't this be fixed by disconnecting type definitions during the build? And, LabVIEW will correctly coerce data between type definitions if the underlying representation is compatible, so even if you ended up with two identical type definitions with different names (due to namespacing), I would think everything would still work without any errors.