From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Private, Community, Friends, Romans, Countrymen

Solved!
Go to solution

LV2013, Win7

 

I'm just getting into using FRIENDS as a scope, and am having some trouble.

 

I have a "manager" VI, which is a WHILE LOOP with uninitialize Shift Registers to remember some data, and a CASE structure inside it.

There is a MANAGER FUNCTION control, an enum with entries like INIT, SHUT DOWN, CONFIG, DO THIS, DO THAT, DO OTHER.

The FUNCTION input controls which case inside the WHILE loop executes.

The manager has several input and output terminals.  One function might need terminals A and D, another function needs terminals B and C, etc.

 

The manager, and all its support VIs are in an LVLIB, which gets built into a LVLIBP (PPL).

My host program used the manager PPL and all is well.

 

HOWEVER

 

Now we introduce an ADDON.  An ADDON is a separate PPL containing a class which is descended from a master ADDON class. Addons might be written by me, or by the customer.

 

The addons can access this manager, and command it to do things.

 

This all works well, too.

 

BUT

 

The addons have access to the WHOLE repertoire of manager functions.  If one of them mistakenly calls INIT, then the manager forgets about stuff it's supposed to remember, and bad things happen.

 

So, I THINK i want to divide up the manager PPL like this:

1... Most of the manager sub functions are PRIVATE.  Invisible to the outside world.

2... the manager VI itself, and the FUNCTION enum with it, are COMMUNITY scope.  As I understand it, they are only visible to items WITHIN the library, and to friends of the library.

3... A couple of "wrapper" VIs simplify public access. Anybody can call the wrappers, the wrapper just provides a FUNCTION command and calls the real manager, and passes only the INs and OUTs required by that one function.

4... I want to make my HOST code a "friend" of the manager, so as to have full access (it's my code in the host, and my code in the manager).

 

All of that works, EXCEPT:

 

I tell the MANAGER library to use my HOST VI as a Friend.

When I then compile the manager into a PPL and then try to LOAD the host, I get an error:

<i>An item named <b>HOST.vi</b> has been loaded from a path that <b>MANAGER.lvlibp</b> does not expect.

If you continue loading, LabVIEW will update <b>MANAGER.lvlibp</b> to refer to the new path.</i>

* C:\Users\Steve\Projects \ My Project\ Host.llb\Host.vi

-> C:\Users\Steve\Projects \ Host.llb\Host.vi

 

Note that the paths are different - one level more in the one that's in memory.

 

I suspect, due to the different paths, that it's complaining about a different relative path from the PPL to the host.

 

1... It claims it's going to "update" the PPL to refer to the new path - how's it going to do that?

2... I can point it to the correct host path, but nothing changes.  It doesn't "update" the PPL (if I load it again, it complains again), and I still can't see anything in the manager PPL except the public stuff.

 

Is there a better way to designate the HOST VI as a friend of the PPL, without being so sensitive to path changes?

It has to work when my host is compiled into an EXE, as well.  Do I declare the manager to have multiple friends?

Should the friend be the VI that I want, or the LLB that contains it, or the EXE that contains it?

 

is there a better way to do what I want?

 

 

 

Steve Bird
Culverson Software - Elegant software that is a pleasure to use.
Culverson.com


Blog for (mostly LabVIEW) programmers: Tips And Tricks

0 Kudos
Message 1 of 13
(3,209 Views)

Maybe I'm figuring it wrong, but it looks like the paths are the same length anyway.

The library exists at

   ProjectSource\Project Standard PPLs\Project Registrar\Project Registrar.LVLIB

 

The host VI is at

    ProjectSource\Project\Project Host.llb\Host.vi

 

I want to make HOST.vi a friend of the library.

I calculate the path as 3 steps down from the library:

    ..\..\..\Project\Project Host.llb\Host.vi

 

When the LVLIB is turned into a PPL, it is a:

    ProjectSource\Project\Project PPLs\Project Registrar.lvlibp

 

It seems like the same path from the LVLIBP to the host, as it was from the LVLIB to the host:

    ..\..\..\Project\Project Host.llb\Host.vi

 

That's the same relative path, unless maybe the LLB doesn't count.

 

What am I missing?

Steve Bird
Culverson Software - Elegant software that is a pleasure to use.
Culverson.com


Blog for (mostly LabVIEW) programmers: Tips And Tricks

0 Kudos
Message 2 of 13
(3,171 Views)

Anybody?

Steve Bird
Culverson Software - Elegant software that is a pleasure to use.
Culverson.com


Blog for (mostly LabVIEW) programmers: Tips And Tricks

0 Kudos
Message 3 of 13
(3,124 Views)

Steve,

 

without a rather small example, the issue is hard to understand.


@CoastalMaineBird wrote:
[...]

The addons have access to the WHOLE repertoire of manager functions.  If one of them mistakenly calls INIT, then the manager forgets about stuff it's supposed to remember, and bad things happen.[...]

 


I am not sure if privacy setting is an appropriate way to deal with above mentioned issue.

If i was the architect for that task, i would create the manager as a self contained service. As a result, the manager provides an API (public methods) and is aware of its own state similar to an actor. That way, a second call into INIT would be discarded and the caller would receive at least a warning via the API.

In the first place, this would result in more development effort. However, i think it's far more robust and easier to extend for future use cases.

Norbert
----------------------------------------------------------------------------------------------------
CEO: What exactly is stopping us from doing this?
Expert: Geometry
Marketing Manager: Just ignore it.
0 Kudos
Message 4 of 13
(3,102 Views)

I guess the root issue is 'How do i designate VI 'A' as a friend of the library 'L', when the relative path between 'L' and 'A' changes, because 'L' gets compiled into a packed library and moved?

Steve Bird
Culverson Software - Elegant software that is a pleasure to use.
Culverson.com


Blog for (mostly LabVIEW) programmers: Tips And Tricks

0 Kudos
Message 5 of 13
(3,093 Views)

a second call into INIT would be discarded and the caller would receive at least a warning via the API.

 

I can see that working for INIT: the first caller wins and subsequent callers are ignored.

but if the function is "SHUTDOWN"... that scheme doesn't work.

 

The problem comes about because the manager was originally designed as a private thing - so all calls are under my control.

Now the addons come along and they need access to it.  Public access works, but exposes more than I would like. So I was hoping to hide part of it behind the "community" label.

Steve Bird
Culverson Software - Elegant software that is a pleasure to use.
Culverson.com


Blog for (mostly LabVIEW) programmers: Tips And Tricks

0 Kudos
Message 6 of 13
(3,086 Views)

@CoastalMaineBird wrote:
[...]

but if the function is "SHUTDOWN"... that scheme doesn't work.

[...]


I can see that this one is challenging. Depending on the complexity necessary, you can provide the following options for this:

1. Simply shut down with the first request. Following shutdown requests would have to deal with a "dead server", meaning they would most likely to have timeouts and error handling implemented

2. Initiate a shutdown and wait some time before really performing the shutdown. This way, most callers should get a notification from a 'not yet shut down server'. Still, for some corner cases, each caller has to include error handling to capture situations where the manager is already shut down

3. Implement the manager as "publish/subscriber" and notify each subscriber as soon as shut down is initiated. That way, each caller has to monitor notifications from the manager and can handle shut down gracefully

 

I took a short look into the friend configuration for items of a library/class. The issue you face is that this is a configuration of the library you place in the PPL. That means that scalability is very limited as you have to define a path and a name which is static for the library.

You can enforce the user to follow a very strict relative path and naming for the plugin in relation to the PPL, but that limits you to have only a single plugin available (per friend entry).

 

I think the biggest concern is knowledge/discipline of developers using your framework: If there is knowledge/discipline, i can imagine that distributing "unprotected" libraries is possible. If there is lack of knowledge/discipline, i would (as mentioned) try to avoid processes which are prone to errors even though that way i would increase my personal work during development.

Norbert
----------------------------------------------------------------------------------------------------
CEO: What exactly is stopping us from doing this?
Expert: Geometry
Marketing Manager: Just ignore it.
Message 7 of 13
(3,073 Views)

That means that scalability is very limited as you have to define a path and a name which is static for the library.

 

Yeah, that's the part I am trying to get around.

I was thinking that if "Host.vi" is a friend of the library, and if "Host.vi" was already loaded in memory, then when the library loads, it finds it's friend right away with no complaint.  After all, that's the way dependencies work.

 

But no.

 

 

Steve Bird
Culverson Software - Elegant software that is a pleasure to use.
Culverson.com


Blog for (mostly LabVIEW) programmers: Tips And Tricks

0 Kudos
Message 8 of 13
(3,069 Views)

If there is knowledge/discipline, i can imagine that distributing "unprotected" libraries is possible.

 

Well, sure, it's possible.  That's what I'm doing now, and it works. But it has this hole where it's possible to muck things up.

 

You've answered the big question (can I do the friends thing), and the answer is "no".

 

Maybe I can put wrappers to the public parts into a separate library (PPL), that's what I give to the public, and the host just works with the manager directly.

 

There would be nothing PREVENTing the public from using the manager directly, but there's a layer of insulation around the high voltage wire.  They wouldn't know about the manager itself, the docs say use this wrapper library, and there are no "friends" involved.

 

Thanks for your thoughts, Norbert.

 

Steve Bird
Culverson Software - Elegant software that is a pleasure to use.
Culverson.com


Blog for (mostly LabVIEW) programmers: Tips And Tricks

0 Kudos
Message 9 of 13
(3,067 Views)
Solution
Accepted by topic author CoastalMaineBird

@CoastalMaineBird wrote:
[...]

I was thinking that if "Host.vi" is a friend of the library, and if "Host.vi" was already loaded in memory, then when the library loads, it finds it's friend right away with no complaint.  After all, that's the way dependencies work.

 

But no.


Honestly, it MUSTN'T work like dependencies (in the common sense). If it would, you could easily fake a friend as soon as you know its name just by making sure to pre-load your fake. This would completely cancel the idea of 'friends'.

Sorry to be strict here....

Norbert
----------------------------------------------------------------------------------------------------
CEO: What exactly is stopping us from doing this?
Expert: Geometry
Marketing Manager: Just ignore it.
Message 10 of 13
(3,061 Views)