LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

What's a good scheme to protect an event in such a way that process B can register but not write/destroy?

Solved!
Go to solution

I want to allow some process A to create a set of events which can then be subscribed to by process B via event registration. However I do not want process B to be able to generate or destroy those events so it can't have direct access to the event refnum.

 

My initial thought was to encapsulate the act of registration in a class method so that process B only ever has access to the registration refnum rather than the event refnums themselves. However that does not allow for other events to be easily registered as well in addition to those provided by process A.

 

 

0 Kudos
Message 1 of 10
(507 Views)
Solution
Accepted by blackburnitearmy

You'll never be able to fully stop it, simply because the act of using an event structure to trigger on a user event will expose the reference in any case through its event data node:

 

Kyle97330_0-1749672265740.png

If you do go with your strategy of registering in a class method they can't access, it's not hard at all for them to register for other things.  Event registrations can be merged with a simple bundle node:

 

Kyle97330_1-1749672454803.png

 

Message 2 of 10
(503 Views)

Ah true, I forgot it exposes the reference in the frame.

 

I didn't know you could bundle the registration refnums like that. I know you could register to multiple events or nest events in bundles, but not the registration itself. Good to know, thanks!

Message 3 of 10
(434 Views)

You could get around this by exposing a new User Event per registering process via an object with a private method. Then your event generator could send the events to ALL user events created. It's more complicated, but it prevents access to the user event directly.

 

Also, there's an article from the Not a Tame Lion blog that might give you some ideas:

 

https://web.archive.org/web/20250125001329/http://www.notatamelion.com/2016/03/22/dynamic-udes-the-p...

 

(I think the blog is down now, so the link's in the wayback machine... and I think he may not have finished the series. But there's still some good stuff in there.)

 

Also, some more discussion in this Idea Exchange entry: https://forums.ni.com/t5/LabVIEW-Idea-Exchange/Don-t-expose-the-Refnum-to-a-pre-registered-User-Even...

 

Yet another way to do this would be to switch from using User Events to something that encapsulates the messaging protocol, like the NI Actor Framework, JDPowell's Messenger Library, or maybe the DQMH (I think- I actually haven't used that one)

0 Kudos
Message 4 of 10
(396 Views)

Or you can register via Callback VIs. (kind of like double-registering Events))

 

You can create a private VI which takes an event refnum, passes it to a Callback VI and then registers this VI (which is provately scoped) for the event. All it does is passes the event on to the users Event. This way, there is no extra loop code and the event refnum the user sees is for the Callback VI, not the original Reference.

 

Producer -> Event -> Callback VI -> Event 2 -> User Code.

 

The User provides Event 2, Callback VI is a VI controlled by the producer and encapsulates the whole operation.

Message 5 of 10
(336 Views)

(Not the OP but curious) I haven't used callback VI's before, though I understand generally what they are.

 

Are you saying the "original event generator" registers the callback VI? I think you're saying that the user creates their own User Event that the API fires, but I don't quite understand how the "original event generator" gets made aware of the User's User Event. If the Callback VI is private then the user isn't calling it to notify the API. I would also guess that the User can't register the Callback VI, since it would be called by the User (and would therefore be out of scope, I think.)

0 Kudos
Message 6 of 10
(321 Views)

@BertMcMahan wrote:

(Not the OP but curious) I haven't used callback VI's before, though I understand generally what they are.

 

Are you saying the "original event generator" registers the callback VI? I think you're saying that the user creates their own User Event that the API fires, but I don't quite understand how the "original event generator" gets made aware of the User's User Event. If the Callback VI is private then the user isn't calling it to notify the API. I would also guess that the User can't register the Callback VI, since it would be called by the User (and would therefore be out of scope, I think.)


Yes, you need to include the originator of the "original" event so that it is not exposed at any time. Otherwise you're exposing the event at the point of registration of the callback and it can still (erroneously or not) be destroyed.

The user code ALSO creates an Event, and the callback reacts to the original and fires the user event. It's like a chain link. Whenever the original event is fired, the callback VI activates (completely autonomously int he background) and does nothing other than take the data from the original event and passes it on in the user code event.

 

So.....

 

Publisher -> Original Event -> Callback VI -> Users Event -> User code.

 

If the callback VI is registered as a function of the publisher, the subscriber only has access to its own code and it's event (the italic portion). Nothing else is within the scope of the subscriber and it cannot do anything wrong with them. If it destroys its own event, the only subscriber affected is itself.

 

This method can also be used for pieces of code which are "closed" and you can implement a middle layer to abstract away the access to the original event and introduce the safety the OP asked for.

Message 7 of 10
(204 Views)

If A and B are classes A should keep the event as an internal reference and have a Public Queue Message-funcion. And/or a packaged Register for Events so you only get the Registration Refnum. 

My bad, you still get the Event ref ...

G# - Award winning reference based OOP for LV, for free! - Qestit VIPM GitHub

Qestit Systems
Certified-LabVIEW-Developer
0 Kudos
Message 8 of 10
(159 Views)

@Yamaeda wrote:

If A and B are classes A should keep the event as an internal reference and have a Public Queue Message-funcion. And/or a packaged Register for Events so you only get the Registration Refnum. 

My bad, you still get the Event ref ...


Correct, see my Idea Exchange entry HERE.

 

16 years ago, BTW. With 17 Kudos. Very much in danger of being denied very soon....😫

Message 9 of 10
(151 Views)

@Intaris wrote:

@Yamaeda wrote:

If A and B are classes A should keep the event as an internal reference and have a Public Queue Message-funcion. And/or a packaged Register for Events so you only get the Registration Refnum. 

My bad, you still get the Event ref ...


Correct, see my Idea Exchange entry HERE.

 

16 years ago, BTW. With 17 Kudos. Very much in danger of being denied very soon....😫


LOL! Now you've got a like from me. 🙂 Haven't thought about it before or seen the suggestion.

G# - Award winning reference based OOP for LV, for free! - Qestit VIPM GitHub

Qestit Systems
Certified-LabVIEW-Developer
0 Kudos
Message 10 of 10
(145 Views)