Jump to content

LabVIEW, GOOP, and the almighty headache


Recommended Posts

At the behest of Tomi... I am posting here.

I have been doing a lot of reading here, the NI forums, and expressionflow.com. Frankly a lot of the theory goes over my head, so I can take it on faith for now. It seems that most articles are really to show you the benefits, but not how base implementation of how OOP in LabVIEW is done. Or I am just to entrenched in data flow... and am having trouble getting my mind around this. Either way.. I want to do this right, and not just work around it. When I envision OOP, I see an object (class) with actions (methods) and adjectives (properties). Well at least in my little mind, I have yet to find an explanation or mapping if you will of LV to OOP at least in layman's terms.

Quick background on me... I have been using LV since 1993, and am a certified architect. I only say this, not to brag, but to give you an idea that I know my way around LabVIEW pretty well. My programming background before LabVIEW was Fortran and Ansi C. I have dabbled a bit in VB, Python, C++ and C# although my abilities are very infantile there. All this being said, I am trying to take advantage of OOP design and implementation in LabVIEW.

So here is the start of my little project (OK there are almost 700 calls that I have to map, the nice things is I have the class breakdowns and descriptions from C++... It is a matter of replicating them in LV. I am wrapping a large library for a mpeg decoder card.

My current project simplified. I am starting with two classes. 1) decoder 2) settings. At a basic level (this is where I am at in this project)

  • I instantiate a new decoder class... No problem, call this hDecoder.

  • I instantiate a new settings class, again no problem, call this hSettings.

Now that I have these two objects, my problem is that I want to 'attach' hSettings to hDecoder. I had assumed that if the decoder class inherits from the settings class, then I could do this... But LV does not seem to allow me to access the data stored in hSettings.

Under the hood, so to speak...the decoder class is instantiated, there is an U32 handle that is a pointer in memory for the decoder that is being utilized.

The same is also true for the settings.

Once those settings are instantiated, they should belong to a specific MPEG Decoder in the PC.

OK now that I have these two things, the next thing I need to do is to INIT the MPEG decoder. This method should belong to the decoder class. This method not only requires hDecoder, but also hSettings. In a nutshell, there is a memory space allocated for me to setup everything that this decoder requires in order to operate. In order to invoke these in the specific decoder, I pass the handle to the specific decoder of the memory space that contains it's settings. These things are handled between the DLL and the driver for the decoder card.

My "work around" is to write a VI (property node, in the settings class) that extracts the U32 handle for that instance of settings, public properties.. that I can call and then store in the decoder class. Well maybe this is not a work around, but it seems to be I should be able to attach the settings to the decoder, and then access that data through passing in the decoder class to it's method of initialize. I am hope I am clear, if not please let me know. Thanks in advance, Paul

Link to comment

QUOTE(Pana-man @ Aug 20 2007, 07:47 PM)

First you are misusing inheritance here. As decoder is not really a setting, you should not make decoder to inherit from setting. Instead, you should put setting class into the private data of decoder. To access the private data of setting class, you need to create methods to the setting class and use these methods within the methods of decoder class to access the settings class private data. In LabVIEW all private data is really private and not protected. That means that you can access the private data only trough class methods when you try to access it outside a method of this class.

QUOTE(Pana-man @ Aug 20 2007, 07:47 PM)

At the behest of Tomi... I am posting here.

Under the hood, so to speak...the decoder class is instantiated, there is an U32 handle that is a pointer in memory for the decoder that is being utilized.

The same is also true for the settings.

...

My "work around" is to write a VI (property node, in the settings class) that extracts the U32 handle for that instance of settings, public properties.. that I can call and then store in the decoder class. Well maybe this is not a work around, but it seems to be I should be able to attach the settings to the decoder, and then access that data through passing in the decoder class to it's method of initialize.

If you need to extract the U32 handle from the settings class private data, you can only do this within the class itself. If you need to use this handle in a method of decoder class, then you need a method for the settings class to get the handle. This method needs to be public as LabVIEW OOP doesn't have any other kinds of ways to access other classes private data.

However I don't know if you need to have the settings class public? It's possible to put multiple classes into a (lvlib) library. Then you can define some of the classes within the library as library private. This way you can have internal classes that may be visible to other classes within the library but not outside the library.

I may have understood something incorrectly, please ask for clarifications if everything wasn't clear.

Link to comment

QUOTE(Tomi Maila @ Aug 20 2007, 01:22 PM)

First you are misusing inheritance here. As decoder is not really a setting, you should not make decoder to inherit from setting. Instead, you should put setting class into the private data of decoder. To access the private data of setting class, you need to create methods to the setting class and use these methods within the methods of decoder class to access the settings class private data. In LabVIEW all private data is really private and not protected. That means that you can access the private data only trough class methods when you try to access it outside a method of this class.

I understand how to do what you are saying, it seems that it is a workaround. I might have performed the inheritance wrongly. decoder != "is a" setting. Rather, decoder "Has a" setting. Thus my desire to 'attach' hSettings to hDecoder. I am not trying to argue, rather I am trying to understand. The end user has reasons to change settings for those instances and , may change them on the fly. Thus a class all to themselves with plenty (about 200) properties (you would be amazed at how many settings an mpeg decoder can have.) However hDecoder need only know the hSetting in order to implement the settings on it's specific decoder.

I think once I get my head around solving this understanding the rest will come quickly.

Link to comment

Did I know understand it correctly. You have a generic decoder interface. Then you have specific decoder interface for your mpeg decoder. You have generic settings interface for all the settings. Then you need to implement the settings interface for the mpeg decoder?

Then you don't need one but two class hierarchies; the settings hierarchy and the decoder hierarchy. You would need a generic decoder class and a specific mpeg decoder class. In addition would need a generic settings class and a specific mpeg settings class. Then you could use composition to set the mpeg settings class as a private data element of your mpeg decoder class.

I trying to draw the picture with a little too little information. Was this something you were intending?

Link to comment

These are not your garden variety decoders. These are professional grade decoders in use at the head ends of TV station transmitters. So no, not a generic decoder. However, one system can handle up to 16 decoders.. that may or may not share the same settings. Does that make sense? There are other classes that I will implement such as a files class... but if I can grasp this interlink... then the rest will come easier.

I guess since LabVIEW OOP does not implement properties... such as a .dot interface. It does make it more difficult.

Link to comment

QUOTE(Pana-man @ Aug 20 2007, 01:29 PM)

These are not your garden variety decoders. These are professional grade decoders in use at the head ends of TV station transmitters. So no, not a generic decoder. However, one system can handle up to 16 decoders.. that may or may not share the same settings. Does that make sense? There are other classes that I will implement such as a files class... but if I can grasp this interlink... then the rest will come easier.

I guess since LabVIEW OOP does not implement properties... such as a .dot interface. It does make it more difficult.

:laugh:

I don't think Tomi was remarking on the quality of your hardware. He was simply describing the software class as "generic" (i.e. a "utility" class that can be inherited from to provide a more specific interface).

Jaegen

Link to comment

QUOTE(Pana-man @ Aug 20 2007, 11:47 AM)

Now that I have these two objects, my problem is that I want to 'attach' hSettings to hDecoder. I had assumed that if the decoder class inherits from the settings class, then I could do this... But LV does not seem to allow me to access the data stored in hSettings.

Without going into your class heirarchy as others have done, it sounds like you're assuming a child class can access the data of the parent from which it is derived. This isn't correct. LabVIEW only has private data, no public or protected data, no friend classes. Accessing a data member of a class higher in the heirarchy requires a member function of the parent class.

Link to comment

QUOTE(Pana-man @ Aug 20 2007, 04:52 PM)

actually the opposite, I expect the parent class to access the data of the child class.

And therein lies the design flaw. The parent doesn't even know it has children. All the VIs in the parent class are written in terms of nothing but the parent fields and the parent methods. Those VIs assume that the data on the wire is some type of Parent, but they can't know anything more specific. Child data may actually be on that Parent wire at run time, but it is behaving as its parent. An example:

Class Shape has data "anchor point" and four member VIs: Get Point, Move, Draw, and Tesselate. Tesselate simply does an iterative "move and draw" over and over to fill in a space. The entirety of Tesselate is written in terms of Shape.

At run time, a Circle may come down the wire. Circle has data "radius". It inherits an anchor point from its parent, Shape. Circle can't access that point directly, but it can use Get Point. Circle defines its own Draw method. Now when Circle is passed to Tesselate, the Tesselate function moves the circle, draws it, and repeats over and over... but the entire time it is not accessing any specific data of Circle. Only when the dynamic dispatch to Draw is done does anything specific to Circle get invoked.

Link to comment

QUOTE(Tomi Maila @ Aug 20 2007, 09:39 PM)

Then you don't need one but two class hierarchies; the settings hierarchy and the decoder hierarchy.

Why don't you just place the decoder settings in the decoder class ? They are the "properties" of that class. Each child class has its own settings as well.

Why separate the decoder functionality from the decoder data (=settings) and create two worlds ?

After all, object = code + data, they are one.

Joris

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.