Jump to content

Determine class hierarchy without loading all VIs


Recommended Posts

Hi All,

I have an architecture that uses dynamically loaded classes for providing custom reports - this way I can add/remove reports from our system without needing to recompile etc.

Currently I have the logic of:

post-9667-085976000 1278940501_thumb.png

(i.e. list all class files and attempt to load & cast as a Report class)

This logic works but it has the problem of loading every single report class and all of its associated VIs etc into memory even if that report was never going to get used by a particular user.

As such, I was wondering if there is a way of determining the inheritance tree of a lvclass file without loading the class into memory (or at least the names of the classes it inherits from)? This way I could do a simple "does lvclass file x claim to inherit from Report" without having to load a whole bunch of potentially unnecessary code. I have had a look at the lvclass XML and figure that this information is hiding in one of the binary (base64?) chunks but cannot seem to find any information of how to extract what I am looking for.

To put it graphically, I would love to create this:

post-9667-091825900 1278941170_thumb.png

Is this possible? Am I crazy for wanting to do this? and more importantly, anyone have any idea how?

Thanks,

Shaun

Link to comment

This logic works but it has the problem of loading every single report class and all of its associated VIs etc into memory even if that report was never going to get used by a particular user.....

....Is this possible? Am I crazy for wanting to do this? and more importantly, anyone have any idea how?

Hi Shaun

Tomi Mali posted a method for this wrt for plugin classes.

It is not exactly what you are asking for, but it will have the same effect (and is easier IMO):

Distribute the class with a text based (or similar) config file - that way you only load a small file and not the entire class (which defeats the purpose of a plugin!) to establish its type: http://expressionflo...-lvoop-plugins/

I have used this before and it works very well.

Link to comment

Yeah, I thought of that... unfortunately I have a trick to simplify things for my users: Each report gets "compiled" to a single "report" file - in reality, I have a build spec that puts the class and all of it's member VIs into a LLB - this makes distributing reports REALLY easy and logical for my end users.

However, as LLBs cannot contain anything other than VIs, CTLs, etc, there is no way to add a text file into the mix.

The LLB issue is actually why finding out info and loading only when needed is such an issue - I have to keep report templates as a compressed string constant in a VI (because LLBs cannot contain Excel / Word files, etc) and because every member VI is loaded into memory, I not only could end up with a whole load of unnecessary code in memory (some users may not use ANY of the reports) but I also could end up with a whole load of compressed Excel files in memory! This obviously adds a whole bunch of loading time / overhead, especially as the number of report options grows, and as some users may not even use a single report, I would really rather something better!

I did come up with one hahe hack - I could screen for *.report files (the LLBs) and go from there. However I was ideally wanting something a little bit more generic - ie something that I could use in source code as well and ideally use in other projects (which may not necessarily use the *.report extension, etc).

Link to comment

Well... it's a hack, but...

You could add a stand-alone .vi file -- one that isn't a member of the class and has a blank panel and diagram -- to the LLB and then put a VI Tag on that VI that has all the info you want to include. Load just that VI and read its tag data to get the info about the class packaged inside the .llb.

It's the best idea I've got this morning.

Link to comment

I was actually just thinking of something similar this morning (only without using VI tags, so that developers who don't know about such things dont get quite so confused ;) ):

post-9667-020291400 1278944132_thumb.png

(admittedly, this does require that someone create quite a specific VI but at least its a relatively easy to describe VI, and after all, that's what documentation is for!)

Link to comment

Okay....being one of those developers who don't know about such things.....What is a VI tag? All the references I could find on the NI site were for HTML tags.

Thanks

Jason

The VI Tags are Private methods that allow to store a tag (variant with a name) in the VI file. They are writable only at edit time but can be read at runtime.

You can get access to these tags through utility VIs provided by NI in the <vi.lib>\UserTags folder.

The best example of how it's being used is the new Icon Editor which supports layers. The icon is still a "flattened image" of all the layers, but each layer content is stored in VI Tags, thus enabling the icon editor to retrieve all layers information even if the icon is flattened (merged layers).

Link to comment

One thing to note is that because the manifest VI can't belong to the class (if it would, opening it would load the entire class) you have to be careful not to load two of them at the same time, or you'll get a conflict.

One generic way of working around this would be to embed the info in the VI's name (e.g. call it "Report_Manifest___XXXXXX", where the Xs are the details you want). That way you don't even have to open the VI.

They are writable only at edit time but can be read at runtime.

Tags are writable at run time, both in the IDE and in the RTE. However, if you want to persist the data in a tag, you have to save the VI, which can only be done in the RTE.

Link to comment

One thing to note is that because the manifest VI can't belong to the class (if it would, opening it would load the entire class) you have to be careful not to load two of them at the same time, or you'll get a conflict.

One generic way of working around this would be to embed the info in the VI's name (e.g. call it "Report_Manifest___XXXXXX", where the Xs are the details you want). That way you don't even have to open the VI.

Yeah, that's what I'm doing - I just wanted to make sure that the loader didnt care what the actual filename was, just that it contained __manifest somewhere in the filename.

In the end, this seems to work although I had a very odd situation for a while where it would take 30s to loop through 8 manifest VIs!!! It seemed to be something to do with the LabVIEW Image Data cluster. I couldnt find a way to actually track it down but my guess what that there was two copiees of the typdef - one inside the LLBs (which got put there by the build definition) and one in VI.lib, so Open VI Ref had to stop and think about which version to use. Either way, disconnecting the cluster from the typedef on the Manifest VIs seemed to solve the problem.

Link to comment

Yeah, I thought of that... unfortunately I have a trick to simplify things for my users: Each report gets "compiled" to a single "report" file - in reality, I have a build spec that puts the class and all of it's member VIs into a LLB - this makes distributing reports REALLY easy and logical for my end users.

However, as LLBs cannot contain anything other than VIs, CTLs, etc, there is no way to add a text file into the mix.

I too distribute classes as .LLBs but I just manage a folder that contains the text files, so never found that a restriction with my application.

The text files then point to the plugin class (e.g. relative path) as well as provide any other info I need.

Using VIs sound like a good idea too.

Link to comment

Ok... you cannot have two VIs in memory of the same name, so the manifest VI cannot have the same name in all the LLBs.

Option 1: What if the manifest VI has the same name as the LLB but with the extension swapped out? That gives you a consistent way to find the manifest VI every time and no risk of collision in memory because each LLB in your directory has to be uniquely named.

Option 2: Name the manifest VI the same thing every time, but put it in a library that is uniquely named and put the library also in the LLB. I hate this option because it piles hacks upon hacks, generating a second useless file to work around the limitations of the first.

Link to comment

Option 1: What if the manifest VI has the same name as the LLB but with the extension swapped out? That gives you a consistent way to find the manifest VI every time and no risk of collision in memory because each LLB in your directory has to be uniquely named.

Thats a naming convention I have used with the text files before and I like it.

Link to comment
  • 5 weeks later...

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.