Tomi Maila Posted December 7, 2007 Report Share Posted December 7, 2007 It is possible to save a VI as a buffer (string) using scripting. A reference to this buffer saved VI can then be opend using scripting as well. The problem with this kind of VI is that LabVIEW doesn't know they exist and cannot recompile them when something referred by the VI changes. I'd like to script a top-level VI for each XNode instance so that the content of the scripted VI depdens on the configuration of the XNode. The important issue here is that the VI must be top-level i.e. I need to be able to call it asynchronously. At execution time XNodes are always called syncrhonously to my knowledge, aren't they? So I was thinking placing a static VI reference on the code generated by the XNode and use this reference to call the VI asynchronously using Run VI method. The problem is that I don't find good solution to do this. If I script a new VI, it needs to be saved somewhere. From usability point of view, the internal VI needs to be unexisting for the user. So I cannot save it into an external file. I could save it as a buffer that's stored as state parameter of the XNode. However I expect that this method would lead into many problems as LabVIEW cannot compile the VI in the buffer when something changes. For example if a VI containing such XNode is opened in another LabVIEW version, the buffer would not be recompiled properly. So I guess the only option I can think of is to save the VI within the XNode containing VI or the XNode instance somehow. I know LabVIEW class controls are VIs stored within an lvclass file. I'd like to kind of save my scripted VI within the VI as a kind of internal subVI that would be recompiled when the outer VI is recompiled. But I've no idea if this is possible. Does anyone have any idea if this is possible? I would not like to use explicit linker depdendesies as Aristos Queue so strongly demanded not to use them. That is always the last option left... Tomi Quote Link to comment
PJM_labview Posted December 7, 2007 Report Share Posted December 7, 2007 Tomi, I have used this VI buffer technique in the past several time (basicaly reading the VI as a text file and saving the end result as default in a string control). I don't understand why you say that LabVIEW will not recompile this VI. As soon you "extract" this VI to disk, it becomes like any other VI. I guess I don't quite understand your use case scenario. Note: I have seen the scripting buffer function and while I never had to try them, I always though that the App:Open.VI from Buffer method was the equivalent of extracting the VI to a temp location and them opening a ref to it. PJM Quote Link to comment
Tomi Maila Posted December 7, 2007 Author Report Share Posted December 7, 2007 QUOTE(PJM_labview @ Dec 6 2007, 07:48 PM) I have used this VI buffer technique in the past several time (basicaly reading the VI as a text file and saving the end result as default in a string control). I don't understand why you say that LabVIEW will not recompile this VI. As soon you "extract" this VI to disk, it becomes like any other VI. I guess I don't quite understand your use case scenario. But in my use case I would never be able to save the VI into a file. It would only exist as a string buffer in a state information of an XNode. As LabVIEW doesn't know this particular string is a VI, it doesn't know that it needs to be recompiled every now and then. I was indeed looking for methods to get it recompiled without saving it to an external file. External file would be usability wise so bad an alternative that I cannot consider it as an option. Nobody would accept a situation where LabVIEW would generate several support VIs for every user defined VI on its own. Only if these VIs can be somehow stored within the VI and LabVIEW would load them into memory together with the VI with front panels closed, only then the solution would be acceptable. So is there a way to store a VI inside another VI and get LabVIEW to load the inner embedded VI into memory when the outer VI loads to memory and compile the inner VI like any other VI and save it together with the outer VI when ever the outer VI is saved? Quote Link to comment
PJM_labview Posted December 7, 2007 Report Share Posted December 7, 2007 Ok, I understand now. This method (although deprecated in 8.5) should do this (I have not test it though). PJM Download File:post-121-1196981358.viLV8.5 Quote Link to comment
Aristos Queue Posted December 8, 2007 Report Share Posted December 8, 2007 QUOTE(Tomi Maila @ Dec 6 2007, 03:27 PM) So is there a way to store a VI inside another VI and get LabVIEW to load the inner embedded VI into memory when the outer VI loads to memory and compile the inner VI like any other VI and save it together with the outer VI when ever the outer VI is saved? Ah, wayward traveler! A word I would whisper in thy ear! Know ye the toolkit known as Block Builder? 'Tis a tool of the devil, the one they call "Express." But in yon toolkit ye shall find the secret that you seek -- the magic of hiding one VI within the confines of another. I canna say how such transsubstantiation is accomplished, for I have ne're learned the trick. But a black magician such as yourself should have no trouble ferreting out the diamond in the rough. Quote Link to comment
Tomi Maila Posted December 8, 2007 Author Report Share Posted December 8, 2007 QUOTE(Aristos Queue @ Dec 7 2007, 07:56 AM) Ah, wayward traveler! A word I would whisper in thy ear! Know ye the toolkit known as Block Builder? 'Tis a tool of the devil, the one they call "Express." But in yon toolkit ye shall find the secret that you seek -- the magic of hiding one VI within the confines of another. I canna say how such transsubstantiation is accomplished, for I have ne're learned the trick. But a black magician such as yourself should have no trouble ferreting out the diamond in the rough. Thank you, ah mister, for thy guidance! Thy words of wisdom of great help are! Lord praise you mister, lord praise. Quote Link to comment
Tomi Maila Posted December 9, 2007 Author Report Share Posted December 9, 2007 Aristos Queue, it works! But only within development environment There seems to be a bug in builder that drops the instance VIs from the build... I reported it to NI and for their shake I hope they will fix it soon. I'm still going to use this method and if not fixed, I guarantee they are going to get a plenty of bug reports from you all If a static VI reference is created into an instance VI (Express VI isntance), the instance VI can be referred using a VI reference. If one wishes to use Run VI method, one needs to place the instance VI itself on a disable diagram to avoid reserving the instance VI for subVI exection when the main VI executes. This method works properly in development environment but build applications exit with internal error. It's presumable that builder simply mistakenly excludes the instance VI from the build. To reproduce: - Open the attached project - Open the only VI in the project - Run VI in the development environment, notice that the instance VI is executed properly - Now close the VI - Build an application according to the build specifications - Execute the application, note that it doesn't execute but stops at internal error Quote Link to comment
Aristos Queue Posted December 10, 2007 Report Share Posted December 10, 2007 QUOTE(Tomi Maila @ Dec 8 2007, 04:18 PM) It's presumable that builder simply mistakenly excludes the instance VI from the build. It's not a mistake to exclude the instance VI... you commented out the Express VI node, thus app builder would assume that the instance VI would never be callable. Try using a case structure with constant FALSE instead (use a control, not a block diagram constant or LV may again get too smart for you). Again, just a guess. Quote Link to comment
Tomi Maila Posted December 10, 2007 Author Report Share Posted December 10, 2007 QUOTE(Aristos Queue @ Dec 9 2007, 09:27 AM) It's not a mistake to exclude the instance VI... you commented out the Express VI node, thus app builder would assume that the instance VI would never be callable. Try using a case structure with constant FALSE instead (use a control, not a block diagram constant or LV may again get too smart for you). Again, just a guess. I diagree. I think it is a bug. All VIs referred by static VI references should be included into the build. Instance VIs should not be any different in this respect. When I place any other subVI on the disable diagram and create a static VI reference to this subVI, builder includes the VI into the build, because I have the static VI reference referring to it. The method suggested using case structure instead of disable diagram doesn't work. LabVIEW reserves all VIs within case structure for subVI execution. Then they cannot be called with RunVI method because they are in a state Run not compatible with top-level exection. Tomi Quote Link to comment
Ton Plomp Posted December 10, 2007 Report Share Posted December 10, 2007 QUOTE(Tomi Maila @ Dec 9 2007, 11:01 AM) I diagree. I think it is a bug. All VIs referred by static VI references should be included into the build. Instance VIs should not be any different in this respect. When I place any other subVI on the disable diagram and create a static VI reference to this subVI, builder includes the VI into the build, because I have the static VI reference referring to it. The method suggested using case structure instead of disable diagram doesn't work. LabVIEW reserves all VIs within case structure for subVI execution. Then they cannot be called with RunVI method because they are in a state Run not compatible with top-level exection. Tomi Reentrancy? Jeff Washington once mentioned that all express VIs needed to be reentrant. Include it explicitly in the build file? Ton Quote Link to comment
Tomi Maila Posted December 10, 2007 Author Report Share Posted December 10, 2007 QUOTE(tcplomp @ Dec 9 2007, 12:18 PM) Include it explicitly in the build file? I don't think this is possible to explicitly include an instance VI into a build. The instance VIs are saved within outer VI and I don't think you can explicitly select them to be included, at least not interactively. Maybe one could edit the build specification manually but that's not very user friendly. I'm working on a user friendly framework and am not ready to accept usability wise poor solutions. An instance VI path is something like C:\My Project\My Outer VI.vi\1 where 1 is the name of the instance VI. The qualified name of the instance VI is My library.lvlib:My Outer VI.vi:Instance:1 Actually I've not tested if instance VI will be included into the same library into which the outer VI belongs to. Tomi Quote Link to comment
Aristos Queue Posted December 10, 2007 Report Share Posted December 10, 2007 QUOTE(Tomi Maila @ Dec 9 2007, 04:01 AM) I diagree. I think it is a bug. All VIs referred by static VI references should be included into the build. Instance VIs should not be any different in this respect. When I place any other subVI on the disable diagram and create a static VI reference to this subVI, builder includes the VI into the build, because I have the static VI reference referring to it. Your logic would hold except for one bad assumption -- you're assuming that instance VIs are like any other VI. But instance VIs aren't regular VIs and were never designed with your use case in mind. They cannot exist without the calling node, and if you strip the calling node during app building then the instance VI goes away. These VIs make a lot of assumptions -- notably that the only caller they ever have is the owner VI. You mess with this assumption at your peril, but it can be done.QUOTE(tcplomp @ Dec 9 2007, 04:18 AM) Reentrancy? Actually, Reentrancy might be the solution, but for a different reason. If the instance VI itself was made reentrant, then you could open a VI Server reference to that instance VI and have a clone of the VI, so even if the subVI was reserved for direct invocation in a case structure (as opposed to a comment node) then you'd still be able to run it independently, I think. Quote Link to comment
Tomi Maila Posted December 10, 2007 Author Report Share Posted December 10, 2007 QUOTE(Aristos Queue @ Dec 9 2007, 11:42 PM) Your logic would hold except for one bad assumption -- you're assuming that instance VIs are like any other VI. But instance VIs aren't regular VIs and were never designed with your use case in mind. They cannot exist without the calling node, and if you strip the calling node during app building then the instance VI goes away. These VIs make a lot of assumptions -- notably that the only caller they ever have is the owner VI. You mess with this assumption at your peril, but it can be done. I don't make any other assumptions than that the LabVIEW works the way it is documented Perhaps I've been using this feature for ages in development environment and now that I try to build an app, it doesn't work Anyway I already reported this as a bug and I'm going to push towards this bug being fixed in the next release. I still think it's a bug without doubt. Language features that work in development environment should also work in the build applications. Nobody can deny this. Let's take shift registers for an example. The intended use is to preserve data from one loop iteration to the next. Then someone came up with functional globals. I guess it wasn't the intended use but it was an excellent use case. Should such apps build properly even though they are using shift registers in contrast to it's original intended use? I guess everyone agrees that these apps should still build properly. I think we are talking about similar issue here. Instance VIs are used as subVIs so far. But the language has allowed creating static VI references to instance VIs since LabVIEW 7 Express I guess. Creating instance VI static references doesn't require black magic or usage of any undocumented features; simply drop an Express VI on BD and then drag it to a static VI reference node. Maybe referring to instance VIs was not the intended usage, but I find it very useful. Should an incorrectly working builder optimization algorithm prevent me from using this language feature? Or should the builder bug be fixed? I'd like to hear other opinions here! Please be free to comment. I'll promise you all something extremely cool later on that takes advantage of this language feature... As for when it comes to using reentrancy as a solution, yes it could work. However I think I need to use reentrancy parameter it its normal use cases. Otherwise it is a good suggestion. Tomi Quote Link to comment
Aristos Queue Posted December 11, 2007 Report Share Posted December 11, 2007 I strongly suggest that you not push this... because the fix is likely to be preventing instance VIs from being referenced through VI references entirely -- given that the design was that these VIs are purely behind the scenes and are designed to have only one caller, it is a bug that they're in the foreground at all. You mentioned only expecting stuff to work that is actually documented. Instance VIs aren't documented at all. Quote Link to comment
Tomi Maila Posted December 11, 2007 Author Report Share Posted December 11, 2007 QUOTE(Aristos Queue @ Dec 10 2007, 05:00 AM) I strongly suggest that you not push this... because the fix is likely to be preventing instance VIs from being referenced through VI references entirely -- given that the design was that these VIs are purely behind the scenes and are designed to have only one caller, it is a bug that they're in the foreground at all. You mentioned only expecting stuff to work that is actually documented. Instance VIs aren't documented at all. I'm afraid I've already reported this issue and for technical reasons I cannot pull it back any more. I hope they are not going to close this hole. I guess it has been around since LV 7 and there is a large possibility that few of LabVIEW users are exploiting this hole. Closing the hole would also cause trouble to these customers. Quote Link to comment
aggieNick02 Posted December 11, 2007 Report Share Posted December 11, 2007 I believe that being able to create a static VI reference to an instance VI "accidentally" happened in LV 8.5. It did not work in LV 8.2. You will likely need a config token from us to be able to create static VI refs to instance VIs in the next release. (It is not that we don't want somebody doing it when they mean to; it is that we don't want somebody accidentally doing it.) I understand and empathize with your frustration. I cannot guarantee anything about future releases, but the code has already been written to improve instance VI behavior in several ways, including making static VI references to them work correctly in appbuilder. Additionally, no guarantees, but you should actually no longer even need the original instance VI call (which you currently have in a conditional disable node). Like AQ expressed, instance VIs were originally designed to have exactly one subVI node caller, and every other use (including static VI refs to them) is a little wonky, but is being made more stable for internal reasons. The LabVIEW Statechart Module uses instance VIs heavily under the hood. Quote Link to comment
Tomi Maila Posted December 11, 2007 Author Report Share Posted December 11, 2007 Nick, thank you very much for your response with insider information It's also nice to hear that NI is using instance VIs itself. And the best of all, I found a workaround to use instance VIs references without static VI references that also builds properly. Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.