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: 

Got those "This VI doesn't match other VIs in the method" Blues

Solved!
Go to solution

Hi guys, me again muddling into OOP.  I'm getting a compile error "This VI doesn't match other VIs in the method".  So what I'm trying to do is this:

 

1) Create a "Communications I-F" parent class, and a "TCP I-F" class as its child.

 

2) The data for the parent is general stuff, common to any interface, timeouts, ACK & NACK strings and such.  The data for the TCP child is specific stuff, IP address, port and a LabVIEW TCP connection ID.

 

3) I make some generic, empty methods in the parent class members like "Open Connection.vi" etc.  They have dynamic  dispatch terminals in the parent class type.

 

4) I make an "Open Connection.vi" member method in the child (all child stuff is in a separate file folder).  The FP and connector pane are identical except that the (dynamic dispatch) class terminals are in my TCP-IF *child class* type.

 

5) Even though I slavishly follow examples (the shipping example "Board Testing - Benefits of Object-Oriented Design" has been my Go-By that I thought would solve all my life's problems), my child's version of "Open Connection.vi" is broken.

 

6) I tried (in the TCP-IF child class) New ==> "VI for override".  But it didn't solve my problem. {what exactly makes it a special "VI for override, anyway? Maybe the (parent) class terminals ar DD?}.

 

What I'm trying to do is a Factory Pattern "plugin" deal for various communication interfaces, BTW.

 

Thanks again and again, guys - paul

Running LV19

0 Kudos
Message 1 of 19
(3,381 Views)

Did you verify that the Required/Recommended/Optional settings for all controls matched between the panels as well?  Also things like reentrancy?

 

If that's not the problem, would you be able to post your entire project and its files as a zip so we can see what the problem could be better than a screenshot?

 

A screenshot of your error dialog would help too.

Message 2 of 19
(3,370 Views)

Thanks Kyle. will do

0 Kudos
Message 3 of 19
(3,334 Views)

So I tried to resume my work from last night and the whole project was completely hosed up.  I started over from scratch - and everything compiles now (Boo! then Yay!).  So my next question is:

 

I'm using Dyno-Dispatch to create HAL plugins.  So the class "TCP I-F" is a child of "Comm I-F Parent".  Now I want to "Open Connection" from a method belonging to the TCP child class.  But I want to use at least one parameter that belongs to the parent class.  I created a set of general parameters for the parent that I thought would apply to any communications tasks.  The data of the TCP child class only contains parameters specific to TCP.  Question #1 - does this make a bit of sense?

 

Question #2 - if you'll look at the diagram for TCP child's method "Open Connection.vi" - what's the Right Way to access the parent's data to use from inside a child's methods?  Create an Accessor VI that's a member of the parent?  Something tells me that I'm missing the point here, that I'm not using the OOP Force, yoda.  Now, I do have methods to load specific data from disk (People Who Know seem to use ini files for this, so I just did the same.  They're not populated yet, at this point I just load the class data with phoney constants to see if I can get at it later to actually use.

 

Thank y'all for reading this! paul

0 Kudos
Message 4 of 19
(3,304 Views)
Solution
Accepted by topic author PaulOfElora

I'm using Dyno-Dispatch to create HAL plugins.  So the class "TCP I-F" is a child of "Comm I-F Parent".  Now I want to "Open Connection" from a method belonging to the TCP child class.  But I want to use at least one parameter that belongs to the parent class.  I created a set of general parameters for the parent that I thought would apply to any communications tasks.  The data of the TCP child class only contains parameters specific to TCP.  Question #1 - does this make a bit of sense?

In general, it makes sense to shift data into the parent class when it is used by more than one child class, yes.

 

 

 

 

Question #2 - if you'll look at the diagram for TCP child's method "Open Connection.vi" - what's the Right Way to access the parent's data to use from inside a child's methods?  Create an Accessor VI that's a member of the parent?  Something tells me that I'm missing the point here, that I'm not using the OOP Force, yoda. 

This is exactly OOP!

You don't read the value directly, but instead use a method of the class to read it. In most cases, the method just reads the value and passes it to the caller. But the value may not always be valid. In this case, the method can do the neccessary steps to compute a valid value, and pass it to the caller. And the caller? It doesn't (need to) know about that, it just calls the method.

 

Now, I do have methods to load specific data from disk (People Who Know seem to use ini files for this, so I just did the same.  They're not populated yet, at this point I just load the class data with phoney constants to see if I can get at it later to actually use.

 

Thank y'all for reading this! paul


ini files are easy to write by hand, and easy to process within LV. So, why not?

Message 5 of 19
(3,287 Views)

Does something like this look correct / useful? I just made a parent data accessor...

0 Kudos
Message 6 of 19
(3,285 Views)

Slowly making progress, EXCEPT... When I select a child object and "load it into" the parent data with To More Specific Class, I lose the parent's data that I had just loaded/initialized.  ANDuh - the output from the TMSC node looks like a child wire - I thought it would be parent! I'm still getting how this works...

0 Kudos
Message 7 of 19
(3,276 Views)

OK so it turns out that I wasn't losing the parent data, I was never actually writing it it there in the first place correctly! So I'm making slow, steady progress, all thanks to you all in this great community. THANK YOU!!

0 Kudos
Message 8 of 19
(3,264 Views)

Hi!

 

Nah, that's not how it works.

Look at this snippet.

 

snip.png

In the beginning, you choose which child class to use.

You then wire this to the LoadClassDataFromFile.vi of the parent.

 

Now, since that VI ist a Dynamic Dispatch VI, magic happens: When the TCP class object arrives at the VI, LabVIEW checks if the TCP class also has a LoadClassDataFromFile.vi, and executes this instead of the one from the parent.

 

Often, you want to run both VIs, The one specific to the child, and the one of the parent. Inside the VI of the child class, place the "Call Parent Method" VI from Cluster, Class&Variant palette. The symbol automatically changes to the icon of the parent VI:

 

snipSub.png

 


May be an other example.

 

I have a device with TCP/IP and RS232 interface, and sometimes use the one, somethimes the other.

 

The two interfaces differ a lot in terms of parameters and how to send/receive, but finally in both cases, a string is sent and a string is received. The formatting of the strings is the same for both interfaces.

 

 

Here is what I did:

 

snipX.png

 

  • I have a TCP class and a RS232 class, both children of a parent class.
  • Each of the TCP / RS232 classes have a normal configuration VI, since the terminal layout differs a lot.
  • Each of the two classes has a dynamic dispatch  connect.vi, send.vi, receive.vi and disconnect.vi with code for the specific interface.
  • The parent class has those VIs, too, but they are empty. In the code above, the (dis)connect.vi of the parent is used, and LabVIEW will call the correct child VI.
  • The communicate.vi exists only in the parent class. It assembles the string sent to the device, and parses the return string. And it just calls the parent send/receive.vi. LabVIEW will call the correct VI, then.
  • The parent class also has functions for all the stuff the device can to. The DiskContent.vi calls the communicate.vi with a constant string, and parses a file list from the reply string. And again: LabVIEW ensures that the correct send/receive.vi buried deep inside there is called.

To sum up: Put all the generic stuff into the parent. For specific code, create empty placeholder VIs in the parent, and VIs in the children which do the actual work.

One last note: It is good to make the classes distinguishable by different colors of the icons. I didn't do it for my example, but for yours.

 

 

Message 9 of 19
(3,209 Views)

I'm repeating myself because I'm sure it can't help your thinking and analysis in the long run to keep referring to your class hierarchies "in the wrong direction."

 

If you start with a child wire and need to cast it to come out like a parent wire, you should use the "To More GENERIC" function.  A parent is more generic than a child.  You keep approaching this and referring to it as though the parent is more specific (and therefore dependent upon) the child.  You need to break this habit early before it muddles your whole way of thinking about things.  Look very closely at the icons for the "To More Generic" and "To More Specific" functions and you'll see that they illustrate the direction of the transform.

 

 

-Kevin P

CAUTION! New LabVIEW adopters -- it's too late for me, but you *can* save yourself. The new subscription policy for LabVIEW puts NI's hand in your wallet for the rest of your working life. Are you sure you're *that* dedicated to LabVIEW? (Summary of my reasons in this post, part of a voluminous thread of mostly complaints starting here).
Message 10 of 19
(3,199 Views)