Jump to content
crelf

Calling an external LabVIEW VI from an EXE

Recommended Posts

I thought this had been fixed before LabVIEW 8, but up until now I'd never had a need to check:

I've got an executable that I've created, and in the spirit of modularity, I'd like to call a VI that is completely external to the exe - it wasn't included anywhere in the build. I use a strict-type call to trawl through a folder with a bunch of VIs in it until I find one with the correct connector pane (an old trick I got from the AAD course a few years ago), and then try to load it. Sure enough, I get a "Error 1003 occurred at Open VI Reference - The VI is not executable." - only VIs that I include in the build (even if they aren't referenced by any other VI) will load properly.

Again, I thought I saw a way around this a while ago - can anyone please enlighten me? :lightbulb:

Share this post


Link to post
Share on other sites
I thought this had been fixed before LabVIEW 8, but up until now I'd never had a need to check:

I've got an executable that I've created, and in the spirit of modularity, I'd like to call a VI that is completely external to the exe - it wasn't included anywhere in the build. I use a strict-type call to trawl through a folder with a bunch of VIs in it until I find one with the correct connector pane (an old trick I got from the AAD course a few years ago), and then try to load it. Sure enough, I get a "Error 1003 occurred at Open VI Reference - The VI is not executable." - only VIs that I include in the build (even if they aren't referenced by any other VI) will load properly.

Again, I thought I saw a way around this a while ago - can anyone please enlighten me? :lightbulb:

I remember going down this path as well. It seemed like you were ok if you had the LV development environment on your computer, but if not it became a real hassle. This technique is useful for plugin's which is probably how you are using it. When I tried to get around the problem of having to have the LV development environment on the machine with the EXE I had to make the "plugin" into an EXE itself, then rename the EXE to an llb, then extract the file out of the LLB using LV, then place it in the folder of interest on the non-LV development machine. If it sounds complicated, it is. I don't remember if I get this technique to work correctly, but I abadoned it because it was quite a bit of hassle for the work I was trying to accomplish.

Surely there is a better way... :wacko:

Chris

Share this post


Link to post
Share on other sites
It seemed like you were ok if you had the LV development environment on your computer, but if not it became a real hassle.

Good point - my test machine has the LabVIEW dev environment on it, but I still can't get it to work - and the final install probably won't have LabVIEW on it :(

Are you suggesting that building a VI in with a generic exe and then copying it out of it again works? :wacko: you're right - that's nuts! :) I wonder if that means that there's some sort of flag in the VI that determines if it's been "built" or not...

Anyone from NI care to chime in on this one? (pleeeeeeeeease?)

Share this post


Link to post
Share on other sites
I thought this had been fixed before LabVIEW 8, but up until now I'd never had a need to check:

......

Hmm... too bad that CLA courses do not teach how to solve problem.

Easy to think it's a bug, but it may not be, you are missing subvis (I will explain below).

[Advertisement ON]

Well, I have figured this out and have been using this plug in technique for quite a FEW years. This plug in technique especially has been intensively used in IVision callback vis and our standalone end application (only LabVIEW runtime engine needed) that uses IVison and data acquisition dynamic called engines etc. Our applications (this and this) have been distributed in different countries with different local languages without problem.

[Advertisement Off]

Make the EXE only for the top level vi, you don't need to include dynamic called vis. Then make a llb for all dynamic called vis, then save the dynamic called vis out of the llb in a folder. And of course your top level vi should point to the right path where these dynamic called vis are. I guess (I am not NI, so guessing) you got error message because your dynamic called vis are broken because couldn't find some subvis. LabVIEW runtime engine does not know where to search for subvis, unlike development environment.

Irene

Share this post


Link to post
Share on other sites

I use the plug-in architecture with executables and it works as expected. It is important that the whole hierachy of the VI be accessible and that the executable installer has correctly installed the required resources (serial, math lib, etc.) I usually do that by Save with option>Application distribution. It saves a lot a VIs that may already be in the app.exe but it is harmless.

If you can give more details on how you proceed maybe we might find the source of the problem... :)

Share this post


Link to post
Share on other sites
I use the plug-in architecture with executables and it works as expected. It is important that the whole hierachy of the VI be accessible and that the executable installer has correctly... I usually do that by Save with option>Application distribution.

I specifically don't want to include my plug-in VIs in the distribution with the executable - I want to call them by name and path only.

Hmm... too bad that CLA courses do not teach how to solve problem.

Very droll Irene (or, at least, I think you're being droll - you forgot to add a smiley to the end of that sentance ;) )

I guess (I am not NI, so guessing) you got error message because your dynamic called vis are broken because couldn't find some subvis. LabVIEW runtime engine does not know where to search for subvis, unlike development environment.

Hmmm - that's just crazy enough to work! My VIs do have subVIs, and I thought that the implicit internal location that is saved within the VIs that I call would be enough to load in the subVIs too... Thanks - I'll give it a shot!

Share this post


Link to post
Share on other sites
Very droll Irene (or, at least, I think you're being droll - you forgot to add a smiley to the end of that sentance ;) )

Ok, :)

Share this post


Link to post
Share on other sites
I specifically don't want to include my plug-in VIs in the distribution with the executable - I want to call them by name and path only.

I think what JP Drolet is saying is that you have to make sure you have all the support libraries (whatever they may be) for your plugging VIs. One way to do that is to actually try to do a source distribution of your plugging including everything (VI.lib etc...).

Your plugging VIs dont have to be part of executable distribution.

PJM

Share this post


Link to post
Share on other sites
I think what JP Drolet is saying is that you have to make sure you have all the support libraries (whatever they may be) for your plugging VIs.

Ahhh - I see: thanks for the clarification. The reason I was confused was that I did have all of my support libraries available - opening a plug-in VI with subVIs worked fine under LabVIEW, and after a couple of experiements, it looks like the very talented (and lovely I might add) Irene looks to be on to something - it looks like the VIs loose their link to their subVIs, resulting in the error message. I'll try a few more experiments tomorrow to confirm that having a VI in the same folder/llb as its' subVIs works - like a flat structure - stay tuned :)

Share this post


Link to post
Share on other sites

LabVIEW knows where vi.lib, user.lib and instr.lib are located but the executable does not. It expects these folders to be in its own application folder. A VI that opens fine in LabVIEW will be broken in your application when subVIs are located in these special folders. They are special in the sense that the path of subVIs located there are stored as symbolic path ( e.g. <userlib>\path\to\sub.vi ) so subVIs are found wherever these libs are located in a particular installation. Other subVIs paths are stored in the caller as relative paths so any changes in relative paths to subVIs will also break the VI. When the VI is opened in an application, all subVIs must be at the symbolic/relative path they are expected or the VI is broken.

That's why saving for application distribution solves the path problems, saving the whole hierarchy at the same place and relinking VIs to the new location.

Since the process might duplicate subVIs (both in application and plugin llb) now when the application opens the plugin VI where the subVIs be loaded from?

First the memory is looked for a VI with the same name. If not found there the internal LLB of the apllication is searched for a VI with the same name. If found there the actual path of the subVIs is ignored and the internal VI has the precedence to be opened. If not found in the internal LLB, the subVIs is looked at the stored relative/symbolic path. Finally, when the subVI is not found, the search paths specified in the search path list (in the options) are searched (the seaurch path can be stored in the app ini file)

Indeed in my first post I didn't mean that the plugin VI to be distributed with the application and its installer but just dropped in a folder where the application will look for plugins.

Share this post


Link to post
Share on other sites
I'll try a few more experiments tomorrow to confirm that having a VI in the same folder/llb as its' subVIs works - like a flat structure - stay tuned :)

I hoped you solved the problem, and not that this helps but I ran into a similar problem with my dynamic loader that I use on lots of test setups. But it occurred on just one customer computer and no other computer so that I could duplicate what was going on. I could not see anything obvious, and so on just that one system I included a bunch of subvi during initialization and the problem seemed to go away. I was convinced there was something about the early version of Win XP on that system but not exactly sure on that. That was LV 7.1 and probably the first XP released.

Share this post


Link to post
Share on other sites
Ok, :)

Thankyou :D

it looks like the VIs loose their link to their subVIs, resulting in the error message. I'll try a few more experiments tomorrow to confirm that having a VI in the same folder/llb as its' subVIs works - like a flat structure - stay tuned :)

Well, I've finished doing some tests, and sure enough - it's all about location location location! As long as your plugin VIs and all of their subVIs are in the same flat location (irrespective of whether it's one big folder or an llb) then it works! As soon as you have a plugin VIs or one of its' subVIs refer to a VI that's outside of that location (even if it's in a subdirectory), then the plugin is toast: "Error 1003 occurred at Open VI Reference - The VI is not executable."

Share this post


Link to post
Share on other sites

I am using a similar approach in LabVIEW 8 and am also getting a "1003" error. Here is a thread regarding that issue:

http://forums.lavag.org/index.php?showtopic=3136

The error occurs if a vi in my plugin and the main executable both call a vi that was from vi.lib. I think it has something to do with the fact that the vi's in vi.lib are now bundled together in locked project libraries.

I can open the plugin vi without any errors in development but get a broken arrow in runtime. The error message is attached when I click on the broken arror in runtime.

Share this post


Link to post
Share on other sites
As long as your plugin VIs and all of their subVIs are in the same flat location (irrespective of whether it's one big folder or an llb) then it works!

After some more research, it seems that you *can* have multiple levels of folders with subVIs all over the place - the problem is that the links between VIs and their subVIs is absolute, not relative. So what's the problem you ask? This screws everything up if you create an installer and bundle your plugins and their subVIs with it (thus moving the VIs from their original locations) - even if you preserve the relative struture, any dynamically called VIs will not be able to find any of it's subVIs unless they are in the same directory as the caller. Please please please - does anyone know how to force the links between a VI and its' subVI to be relative (am I going to need to hack the VI's binary here? :ninja: )

Share this post


Link to post
Share on other sites
After some more research, it seems that you *can* have multiple levels of folders with subVIs all over the place - the problem is that the links between VIs and their subVIs is absolute, not relative. So what's the problem you ask? This screws everything up if you create an installer and bundle your plugins and their subVIs with it (thus moving the VIs from their original locations) - even if you preserve the relative struture, any dynamically called VIs will not be able to find any of it's subVIs unless they are in the same directory as the caller. Please please please - does anyone know how to force the links between a VI and its' subVI to be relative (am I going to need to hack the VI's binary here? :ninja: )

But they actually are relative. If they were absolute, you wouldn't be able to move a project directory without breaking all links to subVIs.

How did you come to the conclusion they were absolute?

Edit: unless there is a major change of behavior in LV8...

Share this post


Link to post
Share on other sites

Hi Folks,

First time posting here - hope this doesn't sound lame or off-topic.

I've found the nastiest gotcha with dynamic calls is when using the call-by-reference-node and I forget to update the type-specifier-for-VI-refnum after a typedef changes - because both the caller and callee look fine. This particular error aside, a nice tool for debugging dynamic-call errors is to open the front panel of the [broken] callee (using Open VI reference and FP.Open). Once opened clicking on the broken-arrow can deliver nice error detail - even in a run-time environment!

Share this post


Link to post
Share on other sites

Seems to me that the next logical step is to compile the modules into EXE form. Then you wouldn't have to worry if all of its subVIs are present, they would simply be part of the exe. I guess the question is; could that main application EXE link to the module code in the plug in EXEs?

Share this post


Link to post
Share on other sites
After some more research, it seems that you *can* have multiple levels of folders with subVIs all over the place - the problem is that the links between VIs and their subVIs is absolute, not relative. So what's the problem you ask? This screws everything up if you create an installer and bundle your plugins and their subVIs with it (thus moving the VIs from their original locations) - even if you preserve the relative struture, any dynamically called VIs will not be able to find any of it's subVIs unless they are in the same directory as the caller. Please please please - does anyone know how to force the links between a VI and its' subVI to be relative (am I going to need to hack the VI's binary here? :ninja: )

Chris,

Sorry to chime in late, but I didn't notice this thread until you mentioned it on the Champions Forum. As others have pointed out your -1003 error is most likely due to missing subVIs. And as mentioned VI links are stored as relative links (the only time they might be absolute is if the linkage spans between drive letters, I think but I haven't tried it lately). It is all about location and knowing what you need to include in your distribution, basically each plugin needs to have all its dependencies available in the spot it expects or somewhere in the VI Search path. So yeah I'm agreeing with everyone here so let me try to throw out a couple of new things to help.

(Tim some of this will apply to you as well, I saw your thread and started a reply but didn't finish it)

Since you are using LabVIEW 8.0 you've got a couple of things you could do to build your plugins:

A) When you define you EXE build specification you can choose to create multiple destinations and have your plugins go into those. Such as a .llb for each plug in. This can be done on by creating new destinations on the Destination Page and checking whether or not the destination is a .llb. Then on the Source File Settings page you can specify which destination files or folders are going. The tricky part is having your dependencies in the project so you can specify them to the different locations easily or to a common location. The good thing about doing this through App Builder is your VIs will get relinked for you even though they aren't all in the .exe file. Also by doing this through the EXE builder you'll only have one copy of your dependencies.

B) Create your EXE through the EXE build specification as you have already done. Then for each plug in create a source distribution for it, where you remove diagrams and set other settings. Source distributions are new for LabVIEW 8.0 but you can think of them as the old Save with Options on steroids (or on crack if you run into a problem :) ). So by doing a Source Distribution per plugin you'll get the plug-in VI plus all its dependencies linked into a new hierarchy of your choosing (you can have it all in one .llb or use the custom packaging to make what ever hierarchy you want. Like building an exe all the linkages will be updated. However if 2 plug-ins use the same subVI unless you plan for that in your building, you'll have 2 copies of the VI on disk. This isn't bad unless the 2 VIs are different some how, the first one loaded will "win", etc just like in the development environment.

I'd recommend method A if your list of plug-ins is "static" meaning you know for this release you have 3 plug-ins but you want them to be dynamic so that all the hit for loading doesn't happen up front or if a plug-in might not run if a certain hardware isn't installed. Method B would be if you wanted a dynamic set of plug-ins and plan on adding them without updating the exe.

Hope this helps some. There is a problem I can think of with .lvlibs using method B that I'll explain on a reply to Tim's post.

Kennon

Share this post


Link to post
Share on other sites

Thanks so much for everyone's help - I appreciate it greatly. I've gone for a combination of options that have resulted in a source distribution of all of the dynamic components. The new Project Explorer has certainly helped me here as it offers a layer of abstraction for the developer - I've created the overall system, and I want my developers to be able to define new and change existing dynamic components without the need to touch the main architecure - I've created an application within an application, and the improvements in LabVIEW 8 have certainly helped. Thanks again - I'm a happy little vegemite! :laugh:

Share this post


Link to post
Share on other sites
...I've gone for a combination of options that have resulted in a source distribution of all of the dynamic components...

Hi, Chris

Can you please explain a little bit how you have finally organized this?

Especially interesting how developer able to debug dynamic components? (Assumed that every developer haven't full source code of core application and all plugins)

best regards,

Andrey.

Share this post


Link to post
Share on other sites

I'm going down the exe with plugin llbs path as well and would appriciate some more fleshing out from Chris, if he doesn't mind!

But another question has come up, can your plugin llbs be created in different LV versions? I.e. could I develop a main EXE in LV 8.2 and write a plugin LLB in LV 7, 7.1, or 8.0.1? Provided I had the RTE that is needed for each specific LV version installed.

Share this post


Link to post
Share on other sites
..can your plugin llbs be created in different LV versions? I.e. could I develop a main EXE in LV 8.2 and write a plugin LLB in LV 7, 7.1, or 8.0.1? Provided I had the RTE that is needed for each specific LV version installed.

Not if your exe is supposed to load the VI. The RTE can not run a VI compiled in another version (At least that's how it used to be and I doubt it was changed).

To do this you would probably need to call another exe, compiled with the appropriate version and pass data back and forth using VI server, making this much more complicated.

Share this post


Link to post
Share on other sites
Ahhh - I see: thanks for the clarification. The reason I was confused was that I did have all of my support libraries available - opening a plug-in VI with subVIs worked fine under LabVIEW, and after a couple of experiements, it looks like the very talented (and lovely I might add) Irene looks to be on to something - it looks like the VIs loose their link to their subVIs, resulting in the error message. I'll try a few more experiments tomorrow to confirm that having a VI in the same folder/llb as its' subVIs works - like a flat structure - stay tuned :)

Well I agree with both of your assertions about Irene :-)

However the problem is not that your VIs "loose" the connection to their subVIs nor that VIs are usually referenced by an absolute path (absolut paths are only used if the volume is different and under Windows this means also a different drive letter) but that VIs located in the "standard" locations such as vi.lib and user.lib are not referenced by their full path ever but by an artificial path similar to "<vi.lib>/local path"

LabVIEW recognizes the special path component <vi.lib> and will search in its vi.lib directory but the runtime system by default has not such a directory (nor has it any other standard search paths configured by default) and will fail locating the VIs in there.

Rolf Kalbermatter

Share this post


Link to post
Share on other sites
As others have pointed out your -1003 error is most likely due to missing subVIs.

Hi,

just wanted to point out that you will also get error -1003 if you try to load a dynamic VI, containing FPGA code, using option 0x08 (reentrant run) in the "Open VI Reference". In this case the error is somewhat misleading as the VI is executable, but not with the selected option.

The developer distribution works great, just create a build for the desired target (include vi.lib, instr.lib if needed).

Build, and download the distribution folder to your target and run your dynamic VI.

/J

Share this post


Link to post
Share on other sites

QUOTE (asd @ May 5 2006, 03:37 AM)

I've found the nastiest gotcha with dynamic calls is when using the call-by-reference-node and I forget to update the type-specifier-for-VI-refnum after a typedef changes - because both the caller and callee look fine. This particular error aside, a nice tool for debugging dynamic-call errors is to open the front panel of the [broken] callee (using Open VI reference and FP.Open). Once opened clicking on the broken-arrow can deliver nice error detail - even in a run-time environment!

Searching on 'dynamic executable' and finding your post got me past a roadblock. Thanks! And I found that besides updating the type-specifier after a typedef changes, you also must prevent yourself from checking on 'disconnect typedefs' in the executable build options.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.