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: 

Object Method as Plugin?

Solved!
Go to solution

Is it possible to dynamically load an object's VI for override (override parent's method) after compiling code into an EXE?

 

I know it is possible to dynamically load objects with a factory, and this can add new objects to compiled code. However, the same doesn't seem to be true for a child's VI for Override. Does the compiled code include what specific implementations are known at compile time? Is there some way to get around this without defining all those VIs ahead of time?

 

To help illustrate this I have attached the image:dynamically load methods.png

 

On the far left, I load in the names of my objects via INI file values. This is useful because if I want to add new objects I can place the class in the appropriate file location and then load it with the ini file value and factory. This will allow me to load objects I did not define when I compiled the EXE. I run into trouble when I try to put the new object through the VI for Override. At that point, it calls the parent method, even if its method exists in its folder on disk. I am sure this is because LabVIEW did not know about that method at compile time. Is there anyway I can dynamically load its method after the EXE has been built? Or am I stuck recompiling my EXE each time I want to add an object with a new VI for Override?

0 Kudos
Message 1 of 17
(2,938 Views)

The compiled exe will only include what is specifically referenced statically (ie directly in your code) or what you additionally include in the build. In your case, you are not including the .lvclass file or the vi methods of the classes you are loading by the factory pattern - these files must therefore exist on disk to be loaded at runtime. LabVIEW is not smart enough to second guess your intentions when you build a compiled exe - it's job is to ensure the the top-level VI you specify has all it's dependencies that are known statically (hence why you must include any dynamically called VIs that are needed unless you plan to load from disk). 

 

However it is entirely possible to load LabVIEW files at runtime dynamically from disk - including LabVIEW Classes. When a LabVIEW Class is loaded into memory it always loads its contents into memory as well at the same time - including any method VIs (dynamic dispatch or not). This gives LabVIEW the ability to execute any of the methods that exist. If a LabVIEW class can't be loaded correctly (eg. the specified class file is missing or a file of the class is missing thus preventing the class from being loaded) then the default reasoning for Get LV Class Default Value is to not notify the user. You can change this behaviour with the "options" optional input. Have a look at the help file for this function.

 

So to summarise - it should work, given that's the point of the Factory pattern.

 

Given that it doesn't appear to in your case my thoughts around debugging are:

  • Does it work at compile time? Are the correct over-rides called? Enabling the LabVIEW dependency loading via the options input is a good way to see what is happening when the load is attempted.
  • Are any of the LabVIEW classes you are trying to load broken? I believe Broken classes can't be loaded (eg. method VIs with errors, child classes that aren't implementing all required overrides or failing to call parent method if specified in the parent etc.)
  • Check the path you are loading your classes from at run-time. Enable debugging on the executable and see whether the correct class is being loaded into memory in each instance of the FOR loop.
0 Kudos
Message 2 of 17
(2,895 Views)

I finally got some time to work on this and the issue was broken methods in my classes in the EXE directory. I fixed those broken VIs and it worked! I could add new classes and their new methods would work! 

 

However, I'm back to where I was earlier. I can add new methods to existing classes and it still calls the original method that was used at compile time. Here is a quick summary of my existing setup:

 

1. It does not work at compile time and the correct overrides are not called. Will the LabVIEW dependency loading help me in this case? The method names are the same, so even if the old one gets loaded and not the new one, its the same name. I don't think I could tell a difference. 

 

2. No broken VIs that I am aware of. 

 

3. I enabled debugging and I can see that the correct overrides are not being called. However, the proper classes are being loaded from disk, they just aren't being used in the override methods.

 

Any other thoughts about this? I just can't figure out why it worked briefly, but now I am back to it not working.

 

 

Thanks,

0 Kudos
Message 3 of 17
(2,800 Views)

Create a new child class which overrides the method you want to change instead of manually doing all the work.  The framework is already there, you just need to use it.

 

Then pass the child around instead of the original object.

 

Shane.

0 Kudos
Message 4 of 17
(2,792 Views)

What exactly do you mean, "manually doing all the work"? 

 

I am creating a new child class, making the new methods, and then moving the class to the proper location in the EXE directory so it can be loaded by the factory. Are you telling me that there is a way to automate that?

 

The child class does get passed around. The problem is that if I add a new class to a program that has already been compiled, then it doesn't use the proper methods for that child.  

0 Kudos
Message 5 of 17
(2,775 Views)

Your OP mentioned dynamically loading a method which infers that you want to replace only a single member VI of a class which cannot be done.

 

Are you sure the methods for your child classes are set to be DD?  I've never had the problem you describe.  Have you tried looking if there's an error returned when loading the classes?

0 Kudos
Message 6 of 17
(2,768 Views)

I did find that replacing a single member VI of a class can't be done the hard way. 🙂   I have been replacing/adding the whole class and all associated files. 

 

I am sure they are set to DD. I create them by selecting "VI for Override". I did have some errors, but have corrected them. I have no errors now and still have the issue.

0 Kudos
Message 7 of 17
(2,759 Views)

Two thoughts come to mind:

  1. How are you copying the new classes to the exe folder? If you simply created them in LabVIEW, then copied in Windows, it probably won't work. This is because by default, separate code from compiled source is turned on and you don't have compiled code to copy. To fix this, create a "Source Distribution" of the new class from the build spec part of the project
  2. Do you have dependencies in the new class that aren't included in the main routine? if so, then the class will not be executable as the dependencies will be missing.
Charles Chickering
Architecture is art with rules.

...and the rules are more like guidelines
0 Kudos
Message 8 of 17
(2,753 Views)

Are you sure you're not renaming the classes when you build your application.  This will likely break the DD chain of any classes loaded later since they'll be pointing to the wrong name in memory.  Also make sure to try unchecking the "remove unused members of project libraries" option.  I believe this could lead to a problem if your child wants to acess a parent functionality which is otherwise not included statically in your placeholder code.

 

But again: Does loading your class from externally raise an error within the EXE or does it load fine?

 

Shane.

0 Kudos
Message 9 of 17
(2,742 Views)

Thanks for the tips Charles_CLA and Intaris. I will try them tonight or tomorrow.

 

Is there a guide or white paper somewhere that discusses how to do this? I've seen lots of discussion on the factory pattern, but not on how to use the factory pattern in an exe to bring in new objects that didn't exist at compile time. Do you know if such a thing exists? I think a guide like that may be of some use to people like me that haven't done it yet.

0 Kudos
Message 10 of 17
(2,723 Views)