Jump to content

Namespacing objects in a build makes them "different"


Recommended Posts

But you defined your plugin interface in terms of an lvclass. You can't have a class in your interface unless both side are going to agree on the class definition. If you really want both side to not share any dependencies, then you can't have any dependencies in the interface between the sides. If your strict VI reference uses any class or typedef, then that definition must be shared. To operate the way you wanted, you can only use core data types in the connector pane of your plugins.

Thanks Greg - that was the definitive answer I was looking for.

Link to comment

I've fallen behind on this topic and don't anticipate being able to keep up with it, but I'll point out a reply I made to Paul in another thread some time ago. It includes some sample code, but I can't quite recall how relevant it would be to this discussion (and don't have access to LabVIEW to check up on it).

If you can look at the example abstractly, this is the type of mechanism I'd use if I had to expose a class which external VIs need to be able to use which an executable will load (and have serendipitously used in the past). At some point the class/classes that are required need to be exported as some sort of distribution. As stated in the other thread, and has been said here, there are many ways to do this (just supply copies of the relevant source code, make a proper source distribution, make a packed library).

Ultimately the distribution does not have to ride along external to your distributed executable-- you just need to make sure the distribution is available to plugin authors to use somehow. Think about a "toolkit" that might be a supplemental item distinct from your core application. Most people won't ever need the toolkit, it can be a separate download, SKU, whatever. If your executable automatically includes all the relevant classes from the toolkit within the executable it is fully functional. Plugin authors just need access to the distribution so they can code up their plugins, but when it comes time to distribute the plugin, they exclude the toolkit files from their distributions because there's no need to distribute them a second time since the executable already has them. More to the point, attempting to include the toolkit classes in a plugin will generate name conflicts as you've seen, so any code which loads plugins ought to do some proper error handling.

Link to comment

I've played around quite a bit with LabVIEW plug-in architectures over the years and they have always fallen short. They work great in development and for modular development, but for deployment, you end up with either having to distribute the plugin source with the deployment/updates (which you might not want to to do) or removing the diagrams (and having a plethora of distribution updates for each target in each LV version).

It wasn't always the case, but now LabVIEW can create DLLs and it makes a lot more sense to use these. Whilst you don;t get away from distros for each target. You at least don't have to create distros for each LV version that the customer may use (and there are a lot of them). They can be loaded and unloaded at run-time, written in any language (including LV) and the plugins can be developed on any platform. Why faff around with LabVIEW specific methods when the OS already provides an elegant one.

Link to comment

Unless I'm missing something with your explanation (which is entirely probable), there's a couple of issues with what you're saying: there's no parent/child heirachy here - in fact, the issue isn't anything to do with LVOOP at all - it's to do with any dependancies with the same name. The more important issue is that I already tried what you're talking about, and it doesn't work: dependancies with the same name cause the Caller to see the Callee as broken.

crelf, I added to the solution I posted on page 1 of this thread a filter block that adds the dependency to lvanalysis.dll to the plugin1+2 and to the caller.

The result was a common lvanalysis.dll for both plugin1+2 lvlibps and another version in the caller.exe inside the data folder. It works just the same.

Those 2 dlls apparently have the same name but actually they have a different prefix. You can learn how the LVLibP does it and do it manually without the lvlibps if you like to but I think that is both funny and redundant.

Does it answer all your needs?

ShaunR, dlls are indeed interesting. I don't think it solves the 32bit/64bit much better or that it is much more stable or easier to manage and update once a change is made, however, for a simple vi that only executes a basic operation, it is quite lovely.

I somehow didn't check the dll options till now. Moreover, I just saw that there is an option to create RESTFull web services :)

Anyhow, if you think the dll solution is as complete as the LVLibP functionality could you please update the version I posted (the callee part) to create dlls that I then could call from the caller?

I want to see what will change and if the shared db class will be the same between the plugins.

I tried doing it myself but I wasn't able to create a dll (I'm probably missing something).

Thanks.

Link to comment

CRelf: It's not easy, but it is straightforward:

https://decibel.ni.com/content/docs/DOC-19176

I think it addresses exactly what you're trying to do. At the very least, there's info therein not covered by the other posts in this thread as far as I can tell.

Honestly, though, my question would be: Why are you using the "append prefix" feature? If you just stop doing that, everything works in your project. If you need a namespace to prevent collisions with some other version of your files that may be used simultaneously, put a library into your *source* and add all the files to that.

Link to comment

CRelf, the plugin architecture Aristos Queue referes to is the one I based my example (posted on page 1 of the thread) on. Instead of going over the link and learning all the pitfalles you could simply use my example and replace the code with yours inside the lvlibs.

there's info therein not covered by the other posts in this thread as far as I can tell.

I gave this same solution with a full implementation. There is info here that is lacking there: how to share a db between two plugins. My example solved it.

Link to comment

Having tried many of the solutions suggested here (and having authored the doc on the dark side about plugin architecture) I have a few comments based on much time spent wrestling with these issues.

You could include your plugins in the application build as "Always Included" files. This doesn't create much of a plugin framework, but in some cases that is acceptable.

Agreed. Since Chris wants "plugins... able to update independently of the application", this is not an option.

You can make the application build put its dependencies outside the application. Create new destination for a sub directory, then change the dependencies to build to there. Then in your plugin projects (Callee's project) reference these files instead of the original "Shared Class" source. Then when Callee is loaded, it will agree on what all the dependencies are named. This is similar to the solution of creating the shared items as another build, but avoids actually having a separate build step.

You're on the right track here, only it's widely considered poor practice to have anything in source directory have dependencies in builds directory.

You can build the shared items as a separate distribution and have both "Caller" and "Callee" projects reference that build output. This doesn't have to be built as a PPL. It could just be a source distribution, but either way it requires a separate project and build increasing maintenance.

... For items that will be referenced from plugins, you can add them to the project directly (instead of having them just show up in dependencies) and not have them be prefixed.

I tried this once - problem is, you end up with duplicate copies of many things in vi.lib. If you want to develop new plug-in code that links to this common source distribution, you can't drop vi.lib functions from the palette anymore. I tried to work around this with a "build wizard": In development, my plug-in would link to vi.lib and other common code as normal, but as a prebuild step the wizard would check all dependencies against the common code library, exclude these from the plug-in build, and perform relinking. The problem I didn't anticipate, is that new plugins often introduced new common dependencies! So, the wizard actually then had to check the main app and all existing plug-ins, to see if any new common dependencies needed to be moved to the common code library distribution, then I had to rebuild the main app and all affected plug-ins. It was a nightmare, and didn't even satisfy the original intent of decoupling.

Here's the idea, illustrated:

Plugins A & B have shared dependecies x & y with the Main App. Loading plug-ins directly from built app doesn't work. Moving x & y to common directory does work if the main app and plug-ins are linked to this common code distribution.

post-4721-0-35839100-1342031808_thumb.pn

But, when we introduce plugin C that has shared dependencies with the Main App (code w) or another Plug-in (code z), then those dependencies must be moved to common or else the new plugin (or existing plugins if the new one is loaded first) will be broken. The fix requires moving w and z to common, and rebuilding Main App and Plugin B.

post-4721-0-61070500-1342031797_thumb.pn

The solution using packed project libraries is a fairly elegant solution to this mess.

post-4721-0-33500100-1342033330.png

Here, the interface is the only common code, built as a packed proj library (to the source directory, and treated as source code). The Main App uses this interface, not directly calling the plugins. The plugins are classes that inherit from a plugin interface class in the built lvlibp (yes, OOP makes this so much simpler). Lvlibp's build all dependencies into their own package using unique namespace. So, although there will be bloat to the program where dependencies are duplicated, the upside is that they can vary independently and not introduce conflicts with other plugins or the Main App.

I'm sure there are other great solutions out there... but this one works for me. Go here for a more thorough step-by-step and example code.

Hope this helps!

Edited by mike_nrao
  • Like 1
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.