Jump to content

Plugin Architecture VI Name Collisions


Recommended Posts

I am using LabVIEW 8 and am building an application that will use a "plugin" architecture. There will be a main program built into an executable that calls sub vi's that are in llb's. Some vi's in the llb's will call DAQmx functions, others will do calculations, etc. Some math functions will be done in the main program too.

The problem I am trying to address is how to deal with vi.lib vi's that are used in the plugin llb vi's and the main program. For example, I use Mean.vi in one of the plugin vi's as well as in the main program. Where should Mean.vi be stored? A name collision occurs if it is in more than one location (i.e. in a plugin llb and the main program executable). This can get very complicated if many vi.lib vi's are used in the plugin llb's and the main program executable. How can I distribute vi.lib vi's that are required for my application to run? The application builder is fine for simple distributions but breaking up the application into several modules (llb's) that have functions (vi's) like a dll has some great advantages.

As side issue, does anyone know of a way to assign a version number of a llb file that is visible from its properties window in Windows?

Link to comment
I am using LabVIEW 8 and am building an application that will use a "plugin" architecture. There will be a main program built into an executable that calls sub vi's that are in llb's. Some vi's in the llb's will call DAQmx functions, others will do calculations, etc. Some math functions will be done in the main program too.

The problem I am trying to address is how to deal with vi.lib vi's that are used in the plugin llb vi's and the main program. For example, I use Mean.vi in one of the plugin vi's as well as in the main program. Where should Mean.vi be stored? A name collision occurs if it is in more than one location (i.e. in a plugin llb and the main program executable). This can get very complicated if many vi.lib vi's are used in the plugin llb's and the main program executable. How can I distribute vi.lib vi's that are required for my application to run? The application builder is fine for simple distributions but breaking up the application into several modules (llb's) that have functions (vi's) like a dll has some great advantages.

As side issue, does anyone know of a way to assign a version number of a llb file that is visible from its properties window in Windows?

Use OpenG's Builder application www.openg.org. It allows you to rename each module of your application. That is what I use for building my application and LLB plugin's for my large system software architectures. I name each module uniquely so I can release each one stand alone without effecting the other modules. I usually leave out the vi.lib and distribute the whole thing with my software. I leave it in the LabVIEW directory and just point to the libdir to the LabVIEW directory in my executable's INI file.

You can do this without renaming though. If all of the names are the same (and the code matches), the vi that is called in your plugin will be the one loaded first (probably in the executable). If you want to seperate the memory space you can also create a new application reference and open the plugin vi's into that (see vi scripting forum for more information).

I do not know of a way to assign a version number for an llb though. I don't believe there is one. They finally added that for LabVIEW EXE's. I usually write installations using SMS installer that will put the version in the registry for me and displays it in a custom "add remove program" application.

If I am not sounding very focused that is because of all the :beer: I drank tonight. :D

Hope this helps.

Link to comment

My application is intended to be run on a computer with only the RTE installed.

I can create a plugin llb out of my vi's using the Build Specifications in LabVIEW 8. I included my user.lib vi's but not the vi.lib vi's. The main application was built from another LabVIEW project into an executable. It uses some of the same user.lib vi's and vi.lib vi's.

The main application executable can call vi's in the plugin vi successfully as long as the RTE can find the vi.lib directory. I made sure it could by copying the entire vi.lib directory into my application directory.

I make the following conclusions:

1. If any vi.lib vi is in a plugin vi and used by the main program executable, a "1003" error occurs (vi not executable) when the main application tries to connect via the vi server to a vi in the plugin llb.

2. A user.lib may be in a plugin vi (and thus in the plugin llb) and used by the main program executable (and thus in the executable file) without any errors.

3. If vi.lib vi's are not included in either the plugin llb or the main executable, the RTE must be able to find vi.lib. I tried using my applications ini file to point it at the vi.lib directory in the LabVIEW directory but could not get that to work. I had to copy the entire vi.lib directory (parts of it may have worked too but figuring out what all to copy is time consuming) to my application directory.

Link to comment
  • 2 weeks later...
The main application executable can call vi's in the plugin vi successfully as long as the RTE can find the vi.lib directory. I made sure it could by copying the entire vi.lib directory into my application directory.

I make the following conclusions:

1. If any vi.lib vi is in a plugin vi and used by the main program executable, a "1003" error occurs (vi not executable) when the main application tries to connect via the vi server to a vi in the plugin llb.

2. A user.lib may be in a plugin vi (and thus in the plugin llb) and used by the main program executable (and thus in the executable file) without any errors.

3. If vi.lib vi's are not included in either the plugin llb or the main executable, the RTE must be able to find vi.lib. I tried using my applications ini file to point it at the vi.lib directory in the LabVIEW directory but could not get that to work. I had to copy the entire vi.lib directory (parts of it may have worked too but figuring out what all to copy is time consuming) to my application directory.

Tim,

Sorry I took me a while to respond to this after I said I would in that other thread.

Ok, so the other thread mentions that in general if you have an EXE that has plugins, the EXE needs to have everything it needs to run and each plugin should have everything it needs to run, in case the EXE changes or some of the plugins aren't in memory. So that should be it for the 1003 error, right? Well there is new way in LabVIEW 8.0 that you can end up with a 1003 error on your plugin VIs if they use VIs from Project Libraries and your EXE uses VIs from the same project Library. You mentioned Mean.vi which is probably one of the VIs that is broken in your plugin and it is part of a Project Library. Also you probably don't have any of your user.lib VIs in Project Libraries, so that is why you are seeing a difference.

The other way to get this 1003 error is by trying to have 2 Project Libraries of the same name in memory at the same time. This doesn't happen in the development environment because there is only one copy of each Project Library. However in an EXE with plugins, where the plugins were built separately from the EXE (Method B from the other post) you can end up with a copy of the .lvlib in the exe and another copy in one or more of the plugins. This seems harmless since the first one in memory is the one that is used (just like VIs), but during the build process we remove unused members of the Project Library in the EXE. And since a VI knows which Project Library it is a member of and a Project Library knows its members. So if the Project Library is already in memory and a VI is loaded that says it is part of the Project Libary, but the Project Library doesn't think the VI is part of it, then the VI will be broken. I think this why you are seeing the 1003 but it works when you load the vi.lib VIs from vi.lib since in there is only one copy of the Project Libraries being used and no references have been removed from them.

Lets take a specific example where you are using some of the Analysis VIs and the EXE only uses Histogram.vi and the plugin only uses FIR.vi (I got a CAR on this last week and wrote a long explanation that I'll copy and paste):

When the exe is built it includes NI_AALBase.lvlib and Histogram.vi in the exe, since Histogram is the only item in NI_AALBase.lvlib used by the exe, App Builder by default removes all the other references that NI_AALBase.lvib has. The new copy of NI_AALBase.lvlib inside the exe is essentially a Project Library with one item referenced in it (there may be some subVIs if Histogram has any that are part of the .lvlib). When the Source Distribution is built the new copy of NI_AALBase.lvlib inside the source distribution has all its references by default because Source Distributions keep them. Even if you trimmed it down in the Build Specification it would only have a reference to FIR.vi which wouldn't be helpful either.

As I said, a VI knows what .lvlib it is a member of and a .lvlib knows what VIs are part of it.

So when the EXE is launched it loads the EXE's copy of NI_AALBase.lvlib into memory. Then the EXE is calling the Source Distribution as a plugin so the VI being called tries to load FIR.vi which knows it is part of NI_AALBase.lvlib, well that is already in memory, so the Run-Time Engine can't load the source dist copy of NI_AALBase.lvlib because a library of the same name is already in memory (so it doesn't matter what links that copy contains). But the copy of NI_AALBase.lvlib in memory reports it doesn't have FIR.vi as a member of it (remember the EXE copy only has a link to Histogram.vi). So FIR.vi is broken because its owning .lvlib isn't found.

The removal of non-essential items is basically a size optimization, so what can be done? Well, not be optimized, by including the entire Project Library into the EXE and the source distribution. That way the 2 new copies of NI_AALBase.lvlib will have links to all the items in it, so the first one loaded will respect everything else.

Either 1) move the NI_AALBase.lvlib out of dependencies into the tree with the rest of your source and include it as a Dynamic VI in the EXE build and Always Include it and its sub items in the Source Distribution. There will still be 2 copies of NI_AALBase.lvlib but they both contain links to all of the items in the Project Library, therefore which ever one loads first, it won't prevent other VIs from running. Also all the items directly referenced by NI_AALBase.lvlib and their dependencies will be included.

Or

2) Uncheck "Disconnect Type Definitions and Remove unused Polymorphic VI instances", that also removes unused .lvlib components if it is checked (maybe we should make those separate options). This will cause all the contents of NI_AALBase.lvlib to be included and the contents of all the .lvlibs it links to. Since NI_AALBase.lvlib contains VIs that have references into NI_AALPro.lvlib, all of it and its dependencies will be included, even if they aren't used by the code. So this can get very big and I wouldn't recommend it (for .lvlibs without circular links, this would be okay).

With method 1 you could also build the .lvlibs and the files referenced by them and their dependencies into the same location on disk. That there would only be one copy and each build would overwrite it.

I have some thoughts on how to make this better for future versions of App Builder/LabVIEW, but right now it only takes what you tell it you need or it takes it all.

Kennon

  • Like 1
Link to comment
Sorry, a bit off topic but...

in the second step of the app builder/installer you add 80Megs of runtime-engine... to my opinion a farce :thumbdown:

Maybe a the topic is drifting but size is an issue to be concerned with and we do need to consider the entire build & distribution process with respect to size, not just the EXE portion. The run-time engine is big, and installer size (thus download size) is probably more of an issue now that EXE size (although the EXE has to go into that installer). We are looking at ways of trimming the RTE down. Of course we are also looking to add more features to LabVIEW which adds more to the RTE. I don't have any progress to report on it getting smaller but I will pester the right people about it.

Kennon

Link to comment
  • 7 months later...

I have been fighting the same issue with LV8.2 the last day or so and have found the following:

1. If I don't include lvlib-files in my exe which my source dist 'plugin' uses, I will get error 2002200 when opening source dist VIs that call vilib members of which the exe-file has the vilib but not the called vilib member.

2. If I include lvlib-files that my exe-app depend on as Dynamic VIs in the EXE build, I will get an error saying polymorphic VIs cannot be added as dynamic VIs.

3. If I include lvlib-files in my exe and don't remove anything the build process takes ages, the exe-file is big, takes long time to load in memory and is slow to execute. Some VIs are still broken in this case, but I haven't figured out why yet. No error, just "this VI is not executable", so maybe a new source dist build will do it, I'll try that.

And if that doesn't work, I guess I'll try renaming or try the OpenG builder.

Edit: I can't do the rename thing or call another app instance since I use a common global (shoot me now! :headbang: ) which won't get updated between instances or if the global VI is renamed.

Link to comment
  • 1 month later...

If you did use separate app instances for your main exe and your plug-in VIs, would this whole problem go away? I am designing a new system that will use plug-in architechture and will need to solve this same issue.

How many app instances can I have and how hard will it be to communicate between them? Anyone have some nice toolkits for managing all this?

-John

Link to comment
  • 1 year later...

QUOTE (kennoncotton @ May 15 2006, 09:32 AM)

Tim,

Sorry I took me a while to respond to this after I said I would in that other thread.

Ok, so the other thread mentions that in general if you have an EXE that has plugins, the EXE needs to have everything it needs to run and each plugin should have everything it needs to run, in case the EXE changes or some of the plugins aren't in memory. So that should be it for the 1003 error, right? Well there is new way in LabVIEW 8.0 that you can end up with a 1003 error on your plugin VIs if they use VIs from Project Libraries and your EXE uses VIs from the same project Library. You mentioned Mean.vi which is probably one of the VIs that is broken in your plugin and it is part of a Project Library. Also you probably don't have any of your user.lib VIs in Project Libraries, so that is why you are seeing a difference.

The other way to get this 1003 error is by trying to have 2 Project Libraries of the same name in memory at the same time. This doesn't happen in the development environment because there is only one copy of each Project Library. However in an EXE with plugins, where the plugins were built separately from the EXE (Method B from the other post) you can end up with a copy of the .lvlib in the exe and another copy in one or more of the plugins. This seems harmless since the first one in memory is the one that is used (just like VIs), but during the build process we remove unused members of the Project Library in the EXE. And since a VI knows which Project Library it is a member of and a Project Library knows its members. So if the Project Library is already in memory and a VI is loaded that says it is part of the Project Libary, but the Project Library doesn't think the VI is part of it, then the VI will be broken. I think this why you are seeing the 1003 but it works when you load the vi.lib VIs from vi.lib since in there is only one copy of the Project Libraries being used and no references have been removed from them.

Lets take a specific example where you are using some of the Analysis VIs and the EXE only uses Histogram.vi and the plugin only uses FIR.vi (I got a CAR on this last week and wrote a long explanation that I'll copy and paste):

When the exe is built it includes NI_AALBase.lvlib and Histogram.vi in the exe, since Histogram is the only item in NI_AALBase.lvlib used by the exe, App Builder by default removes all the other references that NI_AALBase.lvib has. The new copy of NI_AALBase.lvlib inside the exe is essentially a Project Library with one item referenced in it (there may be some subVIs if Histogram has any that are part of the .lvlib). When the Source Distribution is built the new copy of NI_AALBase.lvlib inside the source distribution has all its references by default because Source Distributions keep them. Even if you trimmed it down in the Build Specification it would only have a reference to FIR.vi which wouldn't be helpful either.

As I said, a VI knows what .lvlib it is a member of and a .lvlib knows what VIs are part of it.

So when the EXE is launched it loads the EXE's copy of NI_AALBase.lvlib into memory. Then the EXE is calling the Source Distribution as a plugin so the VI being called tries to load FIR.vi which knows it is part of NI_AALBase.lvlib, well that is already in memory, so the Run-Time Engine can't load the source dist copy of NI_AALBase.lvlib because a library of the same name is already in memory (so it doesn't matter what links that copy contains). But the copy of NI_AALBase.lvlib in memory reports it doesn't have FIR.vi as a member of it (remember the EXE copy only has a link to Histogram.vi). So FIR.vi is broken because its owning .lvlib isn't found.

The removal of non-essential items is basically a size optimization, so what can be done? Well, not be optimized, by including the entire Project Library into the EXE and the source distribution. That way the 2 new copies of NI_AALBase.lvlib will have links to all the items in it, so the first one loaded will respect everything else.

Either 1) move the NI_AALBase.lvlib out of dependencies into the tree with the rest of your source and include it as a Dynamic VI in the EXE build and Always Include it and its sub items in the Source Distribution. There will still be 2 copies of NI_AALBase.lvlib but they both contain links to all of the items in the Project Library, therefore which ever one loads first, it won't prevent other VIs from running. Also all the items directly referenced by NI_AALBase.lvlib and their dependencies will be included.

Or

2) Uncheck "Disconnect Type Definitions and Remove unused Polymorphic VI instances", that also removes unused .lvlib components if it is checked (maybe we should make those separate options). This will cause all the contents of NI_AALBase.lvlib to be included and the contents of all the .lvlibs it links to. Since NI_AALBase.lvlib contains VIs that have references into NI_AALPro.lvlib, all of it and its dependencies will be included, even if they aren't used by the code. So this can get very big and I wouldn't recommend it (for .lvlibs without circular links, this would be okay).

With method 1 you could also build the .lvlibs and the files referenced by them and their dependencies into the same location on disk. That there would only be one copy and each build would overwrite it.

I have some thoughts on how to make this better for future versions of App Builder/LabVIEW, but right now it only takes what you tell it you need or it takes it all.

Kennon

I'm running up against this same problem in an app I'm working on (in 8.2.1) and I have a couple of questions: First, is this still the behavior in LV8.6 when incuding project libraries? Or does 8.6 make handling this situation easier somehow? - I could migrate the project to 8.6 if that will help. Second, if I distribute the original EXE as a LLB (source distibution) it will have copies of the lvlb files that contain all member references, right? And then if I call this LLB from a shell EXE (that does nothing but call the LLB that used to be the EXE) and then the LLB that used to be the EXE calls into another LLB that includes a copy of the same lvlib, there shouldn't be a problem? Right?

Thanks for any help!

Mark

Link to comment
  • 2 years later...

Thank you!

That's very helpful!

Where can I find more intel about this topic?

Tim,

Sorry I took me a while to respond to this after I said I would in that other thread.

Ok, so the other thread mentions that in general if you have an EXE that has plugins, the EXE needs to have everything it needs to run and each plugin should have everything it needs to run, in case the EXE changes or some of the plugins aren't in memory. So that should be it for the 1003 error, right? Well there is new way in LabVIEW 8.0 that you can end up with a 1003 error on your plugin VIs if they use VIs from Project Libraries and your EXE uses VIs from the same project Library. You mentioned Mean.vi which is probably one of the VIs that is broken in your plugin and it is part of a Project Library. Also you probably don't have any of your user.lib VIs in Project Libraries, so that is why you are seeing a difference.

The other way to get this 1003 error is by trying to have 2 Project Libraries of the same name in memory at the same time. This doesn't happen in the development environment because there is only one copy of each Project Library. However in an EXE with plugins, where the plugins were built separately from the EXE (Method B from the other post) you can end up with a copy of the .lvlib in the exe and another copy in one or more of the plugins. This seems harmless since the first one in memory is the one that is used (just like VIs), but during the build process we remove unused members of the Project Library in the EXE. And since a VI knows which Project Library it is a member of and a Project Library knows its members. So if the Project Library is already in memory and a VI is loaded that says it is part of the Project Libary, but the Project Library doesn't think the VI is part of it, then the VI will be broken. I think this why you are seeing the 1003 but it works when you load the vi.lib VIs from vi.lib since in there is only one copy of the Project Libraries being used and no references have been removed from them.

Lets take a specific example where you are using some of the Analysis VIs and the EXE only uses Histogram.vi and the plugin only uses FIR.vi (I got a CAR on this last week and wrote a long explanation that I'll copy and paste):

When the exe is built it includes NI_AALBase.lvlib and Histogram.vi in the exe, since Histogram is the only item in NI_AALBase.lvlib used by the exe, App Builder by default removes all the other references that NI_AALBase.lvib has. The new copy of NI_AALBase.lvlib inside the exe is essentially a Project Library with one item referenced in it (there may be some subVIs if Histogram has any that are part of the .lvlib). When the Source Distribution is built the new copy of NI_AALBase.lvlib inside the source distribution has all its references by default because Source Distributions keep them. Even if you trimmed it down in the Build Specification it would only have a reference to FIR.vi which wouldn't be helpful either.

As I said, a VI knows what .lvlib it is a member of and a .lvlib knows what VIs are part of it.

So when the EXE is launched it loads the EXE's copy of NI_AALBase.lvlib into memory. Then the EXE is calling the Source Distribution as a plugin so the VI being called tries to load FIR.vi which knows it is part of NI_AALBase.lvlib, well that is already in memory, so the Run-Time Engine can't load the source dist copy of NI_AALBase.lvlib because a library of the same name is already in memory (so it doesn't matter what links that copy contains). But the copy of NI_AALBase.lvlib in memory reports it doesn't have FIR.vi as a member of it (remember the EXE copy only has a link to Histogram.vi). So FIR.vi is broken because its owning .lvlib isn't found.

The removal of non-essential items is basically a size optimization, so what can be done? Well, not be optimized, by including the entire Project Library into the EXE and the source distribution. That way the 2 new copies of NI_AALBase.lvlib will have links to all the items in it, so the first one loaded will respect everything else.

Either 1) move the NI_AALBase.lvlib out of dependencies into the tree with the rest of your source and include it as a Dynamic VI in the EXE build and Always Include it and its sub items in the Source Distribution. There will still be 2 copies of NI_AALBase.lvlib but they both contain links to all of the items in the Project Library, therefore which ever one loads first, it won't prevent other VIs from running. Also all the items directly referenced by NI_AALBase.lvlib and their dependencies will be included.

Or

2) Uncheck "Disconnect Type Definitions and Remove unused Polymorphic VI instances", that also removes unused .lvlib components if it is checked (maybe we should make those separate options). This will cause all the contents of NI_AALBase.lvlib to be included and the contents of all the .lvlibs it links to. Since NI_AALBase.lvlib contains VIs that have references into NI_AALPro.lvlib, all of it and its dependencies will be included, even if they aren't used by the code. So this can get very big and I wouldn't recommend it (for .lvlibs without circular links, this would be okay).

With method 1 you could also build the .lvlibs and the files referenced by them and their dependencies into the same location on disk. That there would only be one copy and each build would overwrite it.

I have some thoughts on how to make this better for future versions of App Builder/LabVIEW, but right now it only takes what you tell it you need or it takes it all.

Kennon

Link to comment

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.