Jump to content


Photo
- - - - -

Namespacing objects in a build makes them "different"


  • Please log in to reply
34 replies to this topic

#1 crelf

crelf

    I'm a LAVA, not a fighter.

  • V I Engineering, Inc.
  • 5,742 posts
  • Version:LabVIEW 2012
  • Since:1993

Posted 07 July 2012 - 07:21 PM

I had a difficult time trying to decide which category to put this in - it's a tricky one, so here goes:

I've got a simple application: There's a "Caller" (a built application that the user opens) and a "Callee" VI on disk that the framework opens - nothing too difficult about that so far. The Caller has an object in it where I set some stuff, then I want to pass the object to the Callee through it's connector pane:

Caller.gif

Then, when called, the Callee displays the stuff to the user:

Callee.gif

When I run this in the development environment, it works fine. When I build it, it works fine too.

When I build the Caller application, if I include dependancies (read: subVIs) in the Caller and Callee that are the same (read: have the same name), calling the Callee from the built Caller won't work: it errors out with the Callee being "broken" (it's not really broken, there's just a namespace collision, so it refuses to load it). And I'm cool with that - the solution is to namespace the dependancies in the build, which is fine.

So "what's the problem?!?" I hear you ask!

All this worked great until I started trying to pass an object from the Caller to the Calle through the connector pane. (I think) Since the class is namespaced differently in the built Caller to the non-built Callee, I get

Error 1031 occurred at Open VI Reference in Caller.vi

Possible reason(s):
LabVIEW: VI Reference type does not match VI connector pane.
VI Path: C:\Users\christopher_relf\Desktop\Passing Objects between name-spaced application instances\Callee\Code\Callee.vi


...which, as you can imagine, sucks. I totally understand why it's happeneing, and even agree that this is the way it should be, but that doesn't help me complete my application.

I want to pass an object between a namespaced-exe Caller and a VI Callee - I don't want to deconvolute the object's data to an intermediary (like a variant or string I guess) and rebuild it to a copy of the object on the other side (unless I really have to - but I can't think of a generic way to do it that I like right now). Does anyone have any bright ideas? Hopefully I'm missing something easy, right? :)

I've included an example below.

//Crossposted to NI Discussion Forums.

Attached Files


post-181-1170858537.png


#2 mje

mje

    The 500 club

  • Premium Member
  • 814 posts
  • Location:Milford MA USA
  • Version:LabVIEW 2011
  • Since:1997

Posted 07 July 2012 - 11:38 PM

Sounds to me like this is the sort of thing source distributions were made for. If I recall you can still strip diagrams despite them being called "source" if that's a concern. Put whatever classes are used in the exposed APIs into the distribution and exclude the types from each of your application build specifications.

Packed libraries in theory would work too, but uhh, I'm personally not even close to trusting them given the headaches they've caused me the few times I tried using them.

#3 crelf

crelf

    I'm a LAVA, not a fighter.

  • V I Engineering, Inc.
  • 5,742 posts
  • Version:LabVIEW 2012
  • Since:1993

Posted 07 July 2012 - 11:50 PM

Sounds to me like this is the sort of thing source distributions were made for. If I recall you can still strip diagrams despite them being called "source" if that's a concern. Put whatever classes are used in the exposed APIs into the distribution and exclude the types from each of your application build specifications.

Are you suggesting having a built Caller exe, a Callee vi, and a source distribution with all the shared stuff in the middle? That sounds horrible, and unmanagable.

Packed libraries in theory would work too...

In what way? (I"m actually distributing the Callee and its dependancies in a PPL, but that's beside the point in this scenario).

I'm personally not even close to trusting (PPLs) given the headaches they've caused me the few times I tried using them.

Can you expand on that? I've had a few issues, but mostly due to my own misunderstandings on how they work. Now that I've got a good working knowledge of them, I think they fill a good niche.

post-181-1170858537.png


#4 0_o

0_o

    Very Active

  • Members
  • PipPipPip
  • 90 posts
  • Version:LabVIEW 2011
  • Since:2004

Posted 07 July 2012 - 11:55 PM

Hey crelf,
I'm short on time and I didn't even have time to open your example, thus, I hope I understood your question good enough.
I think I'm doing about the same thing and yet I don't have to play with any namespaces and it works just fine.
I guess the main difference between your implementation and mine is that the callee in my case inherits from a class contanied inside the caller, however, I'm not sure if this is the reason my case works and yours doesn't.
So, I'll try and describe what I did:
1. my caller is a version of the UI Framework https://decibel.ni.c.../docs/DOC-15014
2. my callee is a LVLibP plugin that inherits from a generic class that is conained in the caller's project https://decibel.ni.c.../docs/DOC-19176
3. I pass the status of some subject through a db class (created in the caller) through the connector pane of the callee which while it is being loaded in the callee http://lavag.org/top...rent-subpanels/ see my post there

P.S. - this design is in progress and my boss told me this part of my design works in the deployed version. I didn't see it working with my own eyes until now since I'm busy with some other project at the moment.

We posted at the same minute and I didn't see mje's post :)
I too had some trouble with the LVLibP's at first but it truned out to be a driver problem and once set they work smooth. I love them!

#5 mje

mje

    The 500 club

  • Premium Member
  • 814 posts
  • Location:Milford MA USA
  • Version:LabVIEW 2011
  • Since:1997

Posted 08 July 2012 - 12:49 AM

Well I might not be interpreting your situation correctly. Unfortunately won't be able to look at your example for a while either. But it would seem to me you need some kind of third component. I'm interpreting the situation as you have two executables which you want to operate independent of one another, but want to be able to move (non-serialized, that is native LabVIEW) data between them? That to me implies some sort of common intermediary is needed which contains those types.

As for packed libraries, all I can say is twice I've tried to use them in a large project of mine, and twice I've had to revert because the IDE became simply unusable (slow and unstable). My thought was this third component could in theory be a PPL.

#6 crelf

crelf

    I'm a LAVA, not a fighter.

  • V I Engineering, Inc.
  • 5,742 posts
  • Version:LabVIEW 2012
  • Since:1993

Posted 08 July 2012 - 01:12 AM

I'm interpreting the situation as you have two executables which you want to operate independent of one another...

Nope - one executable that calls a vi.

As for packed libraries, all I can say is twice I've tried to use them in a large project of mine, and twice I've had to revert because the IDE became simply unusable (slow and unstable).

That's really quite interesting - I've never had that issue. Have you got an example, or have you reported that to NI?

My thought was this third component could in theory be a PPL.

I guess it could, but I'd rather not have a third component at all, if possible. Maybe take a look at the code when you get a chance: that should make everything much more clear.

I'm short on time and I didn't even have time to open your example, thus, I hope I understood your question good enough.
I think I'm doing about the same thing and yet I don't have to play with any namespaces and it works just fine.

Thanks for the reply 0_o, but I don't think it quite applies in my situation. I'd apprecaite it if you could take a look at the code I uploaded if you get a few minutes - : that should make everything much more clear.

post-181-1170858537.png


#7 crelf

crelf

    I'm a LAVA, not a fighter.

  • V I Engineering, Inc.
  • 5,742 posts
  • Version:LabVIEW 2012
  • Since:1993

Posted 08 July 2012 - 03:00 AM

PS: I was able to implement a solution in a way that's outside the context of this discussion, although I'd still like to see a solutio to this question.

post-181-1170858537.png


#8 Tim_S

Tim_S

    The 500 club

  • Members
  • PipPipPipPipPip
  • 516 posts
  • Location:Michigan
  • Version:LabVIEW 2011
  • Since:1994

Posted 09 July 2012 - 03:08 PM

My first impression of what you're describing is you're creating a plugin, or at least something very similar. Did I miss something?
Tim

"If this was easy our kids would be doing it." - Coworker

#9 crelf

crelf

    I'm a LAVA, not a fighter.

  • V I Engineering, Inc.
  • 5,742 posts
  • Version:LabVIEW 2012
  • Since:1993

Posted 09 July 2012 - 05:11 PM

My first impression of what you're describing is you're creating a plugin, or at least something very similar.

Yes, that's right.

post-181-1170858537.png


#10 GregR

GregR

    More Active

  • NI
  • 47 posts
  • Location:Austin
  • Version:LabVIEW 2011
  • Since:1992

Posted 09 July 2012 - 10:31 PM

*
POPULAR

It took me a little while to understand that "namespaced" meant using the build option "Apply prefix to all contained items" in "Source File Settings" for dependencies in the build spec. Once I made that connection everything makes sense. This isn't really namespacing. This is changing the name of every dependency. So after the build Caller.vi references a class named "namespace.Shared Class.lvclass". Since Callee.vi didn't go through the build, it references the class "Shared Class.lvclass". A VI that has a single input of type "Shared Class.lvclass" is not going to match a strict VI reference with a single input of type "namespace.Shared Class.lvclass" so the open of the reference fails.

If you are going to rename the class during the build, then all plugins must be rebuilt against the renamed version. You can't really do that if the renamed version is only present inside the application. There are a few other options though.
  • 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.
  • 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 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.
  • You can not rename shared dependencies going into the application. 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. This also will make it clear which items are valid to be referenced from plugins. That makes it clear to you which items might break plugins if you modify them and easier to tell others writing plugins what things they can reference versus items they should not reference.
  • Many other variations of these themes.
To decide which approach to take, I'd want to know what you are really trying to get out of using a plugin approach. Who is going to be building the plugins? Are the plugins supposed to be able to update independently of the application? Should the application be able to update without invalidating the plugins? What VIs/classes used in the application should be able to be referenced from the plugins? What were you trying to accomplish with the name prefixing option?

#11 0_o

0_o

    Very Active

  • Members
  • PipPipPip
  • 90 posts
  • Version:LabVIEW 2011
  • Since:2004

Posted 10 July 2012 - 11:24 AM

As I promised, attached you can find an example of my solution.
In order to execute: Open the zip file, double click the Caller.exe file, fill in the exact directory of ...db version 2 for crelf\builds\Callee Project, run.
Feel free to ask for any further clarification.
Enjoy.

Attached Files



#12 ShaunR

ShaunR

    LabVIEW Archetype

  • Members
  • PipPipPipPipPipPip
  • 2,224 posts
  • Version:LabVIEW 2009
  • Since:1994

Posted 10 July 2012 - 12:10 PM

I would avoid packed libraries if you can. They do not seem to be multi-platform (not even on the same OS).
This is what happens if I try and load your library in LabVIEW 2011 x64 (it loads fine in x32).

Untitled.png
A positive attitude may not solve all your problems, but it will annoy enough people to make it worth the effort. (Herm Albright 1876-1944).

Founder and general mischief maker on www.labview-tools.com.
SQlite aficionado and websocket zealot.
If it 'aint in LabVIEW, then you 'aint got a clue!

#13 0_o

0_o

    Very Active

  • Members
  • PipPipPip
  • 90 posts
  • Version:LabVIEW 2011
  • Since:2004

Posted 10 July 2012 - 12:20 PM

That doesn't come as a complete surprise and it is a bit off topic.
Lets say you were using a driver which is 32bit but you also have another version which is 64bit or for a different platform.
You would have to build a different distribution for each of those cases no matter what tool you are using.
LVLibP is actually an advantage here since all you need is to rebuild all the LVLibPs according to the hierarchy and your application will run on your device.
A simple script can do it and an automatic builder is the place to put it in.

BTW, if someone needs me to convert the code to LV8.2 please ask.

#14 JamesMc86

JamesMc86

    Very Active

  • NI
  • 198 posts
  • Location:UK
  • Version:LabVIEW 2012
  • Since:2006

Posted 10 July 2012 - 12:23 PM

I would avoid packed libraries if you can. They do not seem to be multi-platform (not even on the same OS).
This is what happens if I try and load your library in LabVIEW 2011 x64 (it loads fine in x32).

That is because they are pre-compiled therefore you will only be able to use them on the same processor architecture and OS. Assuming you end up with a built executable this will not matter as you will run on the same runtime engine.

James McNally

AE Specialist, NI UK & Ireland & CLA


#15 ShaunR

ShaunR

    LabVIEW Archetype

  • Members
  • PipPipPipPipPipPip
  • 2,224 posts
  • Version:LabVIEW 2009
  • Since:1994

Posted 10 July 2012 - 01:29 PM

That doesn't come as a complete surprise and it is a bit off topic.
Lets say you were using a driver which is 32bit but you also have another version which is 64bit or for a different platform.
You would have to build a different distribution for each of those cases no matter what tool you are using.
LVLibP is actually an advantage here since all you need is to rebuild all the LVLibPs according to the hierarchy and your application will run on your device.
A simple script can do it and an automatic builder is the place to put it in.

BTW, if someone needs me to convert the code to LV8.2 please ask.

Well. It's not off-topic since it is about code that you posted as an example in this topic
.
If you are happy to limit the portability of your source distributions, That's entirely up to you (I prefer the input from as many people as possible). One of the beauty's of LabVIEW is that it is multi-platform so anyone with LabVIEW x32/x64 or even linux and a Mac can use source posted on the forum. Only those with windows AND LabVIEW x32 can load your source.

That is because they are pre-compiled therefore you will only be able to use them on the same processor architecture and OS. Assuming you end up with a built executable this will not matter as you will run on the same runtime engine.

What is that saying about "assumptions being the mother of all muck-ups"? This is the very reason that I avoid packed lvlibs at all costs. I see no up-side but one huge down-side.
A positive attitude may not solve all your problems, but it will annoy enough people to make it worth the effort. (Herm Albright 1876-1944).

Founder and general mischief maker on www.labview-tools.com.
SQlite aficionado and websocket zealot.
If it 'aint in LabVIEW, then you 'aint got a clue!

#16 JamesMc86

JamesMc86

    Very Active

  • NI
  • 198 posts
  • Location:UK
  • Version:LabVIEW 2012
  • Since:2006

Posted 10 July 2012 - 01:53 PM

I see no up-side but one huge down-side.


That is a downside but an executable is also no good for sharing code on a forum, that's just not what they are for. The trade off that you are making is that the code is precompiled making it much quicker to load, build and having all the compiler optimizations active. The single file makes them easy for distributing plug ins for plugin architectures as well.

James McNally

AE Specialist, NI UK & Ireland & CLA


#17 Tim_S

Tim_S

    The 500 club

  • Members
  • PipPipPipPipPip
  • 516 posts
  • Location:Michigan
  • Version:LabVIEW 2011
  • Since:1994

Posted 10 July 2012 - 01:57 PM

My inclination is to follow the plugin example over on the Dark Side using packed libraries. I have had some trouble with using packed libraries with an error message about including compiled code when trying to create the child objects. I was able to get around this by compiling the parent with the debug flag turned on. There is a fair amount of housekeeping that has to be done to make this structure work, but it's easy to create a new plugin once you've got the setup down.

The portability between 32 and 64 bit Windows concerns me. I'm wondering if there is a problem when an executable that uses plugins that are both built in 32-bit are run on 64-bit. I see an executable loading packed libraries as the use case rather than a VI in the development environment.
Tim

"If this was easy our kids would be doing it." - Coworker

#18 GregR

GregR

    More Active

  • NI
  • 47 posts
  • Location:Austin
  • Version:LabVIEW 2011
  • Since:1992

Posted 10 July 2012 - 02:07 PM

There should be no problem running a 32-bit built application on 64-bit Windows. If you have to support 32-bit Windows, then it probably makes sense to only build as 32-bit rather than having to build everything twice.

#19 asbo

asbo

    I have no idea what you're talking about... so:

  • V I Engineering, Inc.
  • 1,273 posts
  • Version:LabVIEW 2011
  • Since:2008

Posted 10 July 2012 - 02:27 PM

What is that saying about "assumptions being the mother of all muck-ups"? This is the very reason that I avoid packed lvlibs at all costs. I see no up-side but one huge down-side.

If you consider PPLs as a baby step toward a built EXE, then you can approach them with the right mindset: valuable in certain use cases, but completely useless in others.

#20 crelf

crelf

    I'm a LAVA, not a fighter.

  • V I Engineering, Inc.
  • 5,742 posts
  • Version:LabVIEW 2012
  • Since:1993

Posted 10 July 2012 - 04:17 PM

It took me a little while to understand that "namespaced" meant using the build option "Apply prefix to all contained items" in "Source File Settings" for dependencies in the build spec. Once I made that connection everything makes sense. This isn't really namespacing. This is changing the name of every dependency.

You're absolutely right - I should have called it "Namechanged" instead of "Namespaced", or the like.

So after the build Caller.vi references a class named "namespace.Shared Class.lvclass". Since Callee.vi didn't go through the build, it references the class "Shared Class.lvclass". A VI that has a single input of type "Shared Class.lvclass" is not going to match a strict VI reference with a single input of type "namespace.Shared Class.lvclass" so the open of the reference fails. If you are going to rename the class during the build, then all plugins must be rebuilt against the renamed version... There are a few other options though...

Maybe I'm misunderstanding the options you list, but I don't see a solution there. The issue is two fold: I can't load a plugin that has a dependancy that has the same name as one of the application's dependancy (the plugin is reported as broken) - that's why I have to namechange one of them. Your solutions seem to have the dependancies in a shared resource outside the Caller and Callee - won't this have the same issue?

To decide which approach to take, I'd want to know what you are really trying to get out of using a plugin approach. Who is going to be building the plugins?

Anyone on my team.

Are the plugins supposed to be able to update independently of the application?

Yes.

Should the application be able to update without invalidating the plugins?

Yes.

What VIs/classes used in the application should be able to be referenced from the plugins?

I don't understnad this question - are you asking for a list of them?

What were you trying to accomplish with the name prefixing option?

Being able to load the Caller dynamically from the Caller application.

post-181-1170858537.png