02-08-2023 02:08 AM
Hi,
first an overview over my idea.
I have a Bus with several Devices. To control / use those i implemented a Device class and a Bus class, which implement 1..n instances of the Device class. Since all Devices in one Bus use the same Com Interface. So i need one Com Object and give each device a reference to this Com object. The Bus class manages the devices. So my idea was to give the Bus class one instance of the Com class.
My Problem is how to get the reference pointing to the Com object located in the instance of the bus class.
If you need any code snippets, i can provide them.
Additional Information:
I'm not sure, yet i heard that some Objects are not explicitly allocated if the application builder is used. The implementation needs to exported via the application builder. just in case this is of any relevance.
Thank you very much!
02-08-2023 03:42 AM - edited 02-08-2023 03:43 AM
If you want a reference to an object, you can create a DVR (Data Value Reference) that contains this object (your "Com" object in your case).
Then you can pass this reference to whatever class you want ("Bus" and "Device" in your case) and store it in their private data.
In this way, you only have 1 instance of the Com object, no duplicate.
Some considerations though:
- the object contained in the DVR must be accessed through an "In Place Element Structure", which temporary locks the reference to prevent race conditions, but can also cause dead locks if wrongly used.
- the DVR must be destroyed when not used anymore to prevent memory leaks.
- the reference creation restriction must be unchecked from the properties page of your class (section "Inheritance").
You may want to look into free tools like G# or GOOP, which puts a framework to the creation of objects by reference.
02-09-2023 01:55 AM
Hi raphschru,
Thank you for your fast reply!
I tried a minimal example for this, yet it seems that the shared resource is not refreshing with changes made to the DVR.
Sorry for attaching a zip, yet the forum says it won't accept a .lvclass as a file.
The attached class has a test.vi where i tried the procedure.
To keep the test small and easy i used a Boolean LED as the shared resource and tried to change it via the DVR.
02-09-2023 03:43 AM
Hi Yannick,
It seems you are reading the led value from the object's private data directly.
What you need is reading the value inside the reference through the In Place Element Structure instead.
Some advices:
- If you create a reference to some data, it is because you want to access it by reference. So it is better to avoid having multiples copies of the data at other places (like you did in the private class data). Otherwise, you would have to keep the values in sync, which could cause additional trouble.
- No need to rewrite your reference to your private data each time you use it, because a reference does not change its value once it has been created.
Here is your code corrected:
02-09-2023 03:59 AM
Hi raphschru,
Okay thank you very much. I guess i see my mistake.
I expected the DVR to point to the original Object. So i assumed i can read the Object by itself and via the reference. That's why i tried writing to the reference and reading the object.
But it seems to copy the object somewhere unspecified and keeps that object as long as the DVR exists. So i don't have access to my originally created Object? Only over the generated Reference?
02-09-2023 04:02 AM - edited 02-09-2023 04:05 AM
@YannickRa wrote:
Hi,
first an overview over my idea.
I have a Bus with several Devices. To control / use those i implemented a Device class and a Bus class, which implement 1..n instances of the Device class. Since all Devices in one Bus use the same Com Interface. So i need one Com Object and give each device a reference to this Com object. The Bus class manages the devices. So my idea was to give the Bus class one instance of the Com class.
My Problem is how to get the reference pointing to the Com object located in the instance of the bus class.
Why do you need a reference? VISA is already a reference.
If preventing parallel access is the problem, I'd solve that in the Com class, not in the caller(s).
The com class can solve this with a DVR, or 1 element queue, etc.
It can also be solved by making 1 VI with a few functions, and make it non-reentrent. This let's LabVIEW manage the interlocking.
You can even make the com class communicate with a dynamic com manager (singleton, 'actor'), so all traffic of the com class is send to the manager.
I never use a DVR unless I have to. They make debugging so much harder, although in this case the com resource probably dies with the DVR anyway.
If you call all devices in a loop (sequential), you don't need to worry about parallel access at all. There doesn't need to be anything by reference, except the visa reference.
02-09-2023 04:33 AM
wiebe@CARYA wrote:
Why do you need a reference? VISA is already a reference.
I don't use the VISA's. It's a company intern Interface class.
The point is that i don't want multiple copies of the same interface object, but one object used by all devices in the Bus.
Parallel Access is not really a concern since the Bus object tells each Device what to do. These commands are all sequentiell.
02-09-2023 05:05 AM
@YannickRa wrote:
wiebe@CARYA wrote:
Why do you need a reference? VISA is already a reference.
I don't use the VISA's. It's a company intern Interface class.
The point is that i don't want multiple copies of the same interface object, but one object used by all devices in the Bus.
Parallel Access is not really a concern since the Bus object tells each Device what to do. These commands are all sequentiell.
Most of what I said still applies.
If a class is by reference, or a singleton, the class should handle that, not the callers.
So you can still make the class communicate with a broker, so you have centralized IO.
Or put the DVR in the com class, so you have a by reference class.
If all commands are sequential, why do you need a copy of the com class? Pass it as an input to device methods that use it. Pass the changed com object as an output. Wire it to the next device in the sequence (or loop). That is wire flow, no references required! And also no copies.
The device classes don't need to own the com object. They use it.
I don't know what it is you're trying to make, or if this would work for you.
I do know this is the phase where it pays off to spend a lot of time thinking. It takes time to make things simple...