LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Error 7 When Calling a Class In an Executable on cRIO target

Solved!
Go to solution

Dear all

 

I built a HAL based on OOP where I am loading classes dynamically (more precisely I rely on an approach known as Factory Pattern).

These classes are then organized in different libraries (e.g.: RS232.lvclass is in RS232.lvlib; RS485.lvclass is in RS485.lvlib, ...)

GeorgB_0-1689941669652.png

 

In development mode, everything is loaded fine on my cRIO and I have no troubles.

When I build an .exe and deploy to the target, my application cannot find the classes and throughs an error:

Get LV Class Default Value.vi<APPEND>

<b>Complete call chain:</b>
Get LV Class Default Value.vi
Interface Data.lvlib:Select Interface_RS232.vi
RT COM - CS125.lvlib:Worker.vi
RT Init - Sensors.vi

 


RT - Modules.lvlib:Init.vi
RT main.vi

<b>LabVIEW attempted to load the class at this path:</b>
/home/lvuser/natinst/bin/RS232.lvlib/RS232.lvclass

 

 

I have browsed several posts and according to these the directory should be correct.

I also included my classes into the build as "always included" accordingly.

GeorgB_1-1689942068006.png

 

I simply don't get straight, what my problem is or if a class being inside a library is handled differently.

See posts I already checked and didn't help me out.

https://lavag.org/topic/21715-factory-pattern-on-a-vi-running-on-rt-target/

https://knowledge.ni.com/KnowledgeArticleDetails?id=kA03q000000wvv5CAA&l=de-AT

https://knowledge.ni.com/KnowledgeArticleDetails?id=kA00Z0000019O6PSAU&l=de-AT

 

I hope for some help.

BR Georg

 

 

0 Kudos
Message 1 of 6
(1,023 Views)

Simple debug suggestion - do a recursive file list of the directory where you think the classes are located, and log that to disk for review.

 

You could also drop that class constant somewhere on your block diagram and get the path, then log that. 

0 Kudos
Message 2 of 6
(991 Views)

Thanks for the quick reply.

 

Similar to your suggestion I tried the solution provided here:

https://forums.ni.com/t5/LabVIEW/Executable-can-t-load-class/td-p/4210800

where I simply dropped the classes in a "dummy load case structure".

But it messed around with the path during development instead. 

 

In my opinion, the main difference to the solution in the above mentioned thread is that I use classes put in libraries that are maybe not recognized. 

0 Kudos
Message 3 of 6
(965 Views)

Why would putting the classes on the block diagram change the path during development?

 

I was suggesting you do the recursive file list because it will tell you the actual paths of the classes in the built exe. You may need to use the fully qualified name of the class, including the library.

0 Kudos
Message 4 of 6
(956 Views)
Solution
Accepted by topic author GeorgB

I solved my problem!

Or at least only one last wrong class is loaded.

 

Your suggestion with the recursive file list indeed helped me out. I tested for one class - RS232lvclass - and I checked out the list which returned me that path:

home:\lvuser\natinst\bin\startup.rtexe\Modules\Communication (RT Com)\RT Com - externalInterfaces\Peripherals OOP\Interface\Interfaces\RS232\RS232.lvclass

 

Now, this lead me to two findings:

  1. classes do not need to be loaded with the library => RS232.lvlib/RS232.lvclass is therefore wrong
  2. in the build properties I dropped the classes to "always included". However, per default such files are loaded to the destination of the startup.rtexe (or whatever your Target filename is). This is why it includes the whole path of my project structure to it.

GeorgB_0-1690025107477.png

 

So, what I did instead was to create another destination folder called OOP Classes. In the Source File Settings tab I then changed for each class the destination to the OOP Classes folder. Of course, I also needed to change in my code the relative path setting for each class to /OOP Classes/MyClass.lvclass.

 

Now, I need to solve how to distinguish between development mode where /MyClass.lvlib/MyClass.lvclass is required and App mode where the above path is needed.

But obviously the Get LV Class Default Value.vi searches for missing dependencies anyway. 

Also, this solution is not very sound.

 

BR Georg

0 Kudos
Message 5 of 6
(926 Views)

  1. classes do not need to be loaded with the library => RS232.lvlib/RS232.lvclass is therefore wrong

I think you are confusing loading classes by name and by path. Loading by name requires the fully qualified name, which includes the containing library. In the post you linked where all classes in subfolders are loaded, you would load the class by name, because they are in memory and stay there (LabVIEW does not unload classes). This of course defeats the purpose of loading by path: loading the class into memory only when needed.

 

Why do you need to load the classes by name or path at all? If you do not add or change classes after deployment, the only benefit is decreasing initial load times, right? You could use a factory method that takes an enum wired to a case structure where every case has a proper class instance in it. You have to create and update that method, but in turn do not need to worry about including the classes in the build spec and setting the proper path or adjusting paths for development and executable.

0 Kudos
Message 6 of 6
(912 Views)