05-08-2012 11:02 AM
Hello all.
I have a question about references to LV class member functions. I have a small example to demonstrate my problem.
My test class Base implements a reentrant public dynamic dispatch member function, doSomething.vi.
Another test class, Child, inherits Base and overrides the implementation of doSomething.vi.
Now say I have an array of Base objects (which could include any objects from classes that inherit Base). I want to run the doSomething methods for all the objects in the array in parallel.
In C++, I'd define a pointer to the virtual member function doSomething, and use it with each object in the array and the correct version of doSomething would be called.
In Labview, the only way I've found to do it is like this:
This is less than ideal, because it relies on every child class implementing doSomething, and relies on specific names for the inputs to the method.
Is there a better way to do this?
Thank you,
Zola
05-08-2012 11:15 AM
Why not just use the "DoSomething" from that parent class inside the loop at let the dynamic dispatching do its job?
In this code I am invoking a method of teh parent to find the names of compatabel plug-ins.
Yes that error wire is a typo.
I have other LVOOP images here.
Sorry if this does not help but based on your question I am not sure what you are trying to accomplish.
Ben
05-08-2012 11:24 AM
Hi Ben,
Thanks for the response. I might be missing something in your reply, but I want to run all the doSomethings for the objects in my array in parallel, not in sequence.
Best Regards,
Zola.
05-08-2012 11:34 AM
Try looking at Dr Damien's Nugget here and let me know if you are getting any closer to a sloution.
Ben
05-09-2012 07:36 AM
Thanks, Ben. I don't think I'm any closer to a better solution though.
My first example works, but I don't like the limitations it imposes. I'm looking for a better way to do it.
My problem is this:
So I want it to invoke Run VI for the right version of doSomething.vi according to the object's class.
I tried doing this, just as an experiment:
It doesn't work. Although the Child object is cast to the right class, the code still always calls Base::doSomething.vi.
So, how do I get the VI reference to the correct doSomething.vi to invoke VI Run if I don't do it via class name (as shown in my first example)?
05-09-2012 07:41 AM
I'm adding the test/example project for info. The calling test.vi is the top level VI which works.
05-09-2012 08:00 AM
I still suspect you are over-working this code and not leting LVOOP do tis thing.
As I understand it you want to creae an active object but detemine its class at run time. The recent Architect summit touched on messaging for what they are calling a "worker Pool" pattern or what-not. YOu may want to search on the summit stuff. lacking that I'll share some images of where I did something similar ( I think). Note this is an older app and new stuff like the "Start Asyncronous call..." has been introduced making this even easier.
I want to create a new Active Object (thread running in the background) so I invoke a method to do so
It invokes the following that create some queues for talking to it and getting info back.
Time does not permit me doing a complete write-up but I have assembled the above images into a LVOOP Albumn found here.
When you click on one of those images you will get a large view as shown in this example.
Just below that image you will find a link to the original thread where I posted the image and talked about it.
I believe the best I can do for you at the moment is to urge you to browse my albumn and chase the links.
That agllery was assembled in an attmept to help you and other before you asked. I hope it is helpful.
Ben
05-09-2012 11:42 AM
Okay, I've found a better solution. The key was discovering the LVClassLibrary.HasImplementation method. That will search the class hierarchy on a given class to find an implementation of a named method.
Here's a function (run class method.vi) to programmatically run a method for an object given the object, the name of the method, and the index and value for any front panel controls you want to initialise.
Here's how I call it:
I've attached the test project including this VI (run class method.vi). Look at other calling test.vi to see it in action.
07-05-2017 06:31 AM
This provided exactly what I was looking for.
However, the RUN CLASS METHOD.vi as shown has a flaw:
If the CONTROL VALUES array is empty, then the FOR loop runs 0 times, and the VI REFERENCE coming out of it will be the default value, nil.
One should use a SHIFT REGISTER to pass the VI REFERENCE in and out, and then if it runs 0 times, the ref is unchanged.
Blog for (mostly LabVIEW) programmers: Tips And Tricks
07-05-2017 09:55 AM
Also note that the LVCLASS.OPEN method is not available in the RunTime Engine, nor on LVRT.
A better tool would be the GET IMPLEMENTING VI PATH method - provide it with a Path to the class, a method name, and an access scope constant, and you get a path to the method for this class, or the closest parent method.
Blog for (mostly LabVIEW) programmers: Tips And Tricks