Jump to content

Finding out LabVOOP object runtime class


Recommended Posts

You can convert LabVOOP wire to variant (To Variant function). It gives information on type and value (check show type on Variant indicator).

With OpenG' Data tools, you can have maybe these informations formated into String.

Those tools won't tell you about a LVClass. They predate LVClasses. Unless someone has issued a patch that I don't know about.

Link to post
Share on other sites
Does anybody know how to interpret the type string output of "Variant To Flattened String" node when a class is connected to the variant input?

Yes, Stephen knows, I'm sure ;)

It probably wouldn't take a whole lot of reverse engineering thoughtful inspection to figure it out.

Link to post
Share on other sites
It probably wouldn't take a whole lot of reverse engineering thoughtful inspection to figure it out.

I just wonder if there are many special cases that may affect the type string such as the class belonging to a library or the class being derived from another class etc. And later on when there are classes implementing interfaces and such the code should still work, and it may not if we are not certain about the special cases.

Link to post
Share on other sites
I just wonder if there are many special cases that may affect the type string such as the class belonging to a library or the class being derived from another class etc. And later on when there are classes implementing interfaces and such the code should still work, and it may not if we are not certain about the special cases.

My guess (I haven't tested anything, yet) is that the type descriptor of an lvclass only references it by name and you will need to open a VI server reference to the .lvclass, in order to get all the nitty gritty info.

Link to post
Share on other sites
My guess (I haven't tested anything, yet) is that the type descriptor of an lvclass only references it by name and you will need to open a VI server reference to the .lvclass, in order to get all the nitty gritty info.

But you don't know the path to the class by just knowing the in memory name. And there is not such a scripting property I know of that would return "All Classes in Memory". Of course you can get "All VIs in memory" and then try to figure out which class each VI belongs and store them to some sort of set of all classes and then you can compare your class agains all the classes in the "set of all classes"... well complicated. Anyhow for my purposes I just would like to use the class name in a indicator that would be able to show at least some information of all the classes...

Hmmm... there is this probe for objects. I wonder if it's implemented in pure G and if the block diagram is not locked...

Link to post
Share on other sites
But you don't know the path to the class by just knowing the in memory name. And there is not such a scripting property I know of that would return "All Classes in Memory". Of course you can get "All VIs in memory" and then try to figure out which class each VI belongs and store them to some sort of set of all classes and then you can compare your class agains all the classes in the "set of all classes"... well complicated. Anyhow for my purposes I just would like to use the class name in a indicator that would be able to show at least some information of all the classes...

Hmmm... there is this probe for objects. I wonder if it's implemented in pure G and if the block diagram is not locked...

Jim is correct the type string and the data string both just contain the class name (which can easily be extracted). To get a VI reference, just build the private data cluster (which must be in memory). My example is "TestClass.lvclass:TestClass.ctl". From here you can get the path and even the private data cluster.

Download File:post-987-1165272751.vi

Download File:post-987-1165272777.vi

Download File:post-987-1165272895.zip

(*.lvclass extension is not allowed?)

Brian

Link to post
Share on other sites
But you don't know the path to the class by just knowing the in memory name. And there is not such a scripting property I know of that would return "All Classes in Memory". Of course you can get "All VIs in memory" and then try to figure out which class each VI belongs and store them to some sort of set of all classes and then you can compare your class agains all the classes in the "set of all classes"... well complicated. Anyhow for my purposes I just would like to use the class name in a indicator that would be able to show at least some information of all the classes...

Hmmm... there is this probe for objects. I wonder if it's implemented in pure G and if the block diagram is not locked...

Here is a tool that should work (I just whipped it up). It depends on the OpenG oglib_lvdata library. After some testing and clean-up, I'll add it to the oglib_lvdata library.

Cheers,

-Jim

Download File:post-17-1165273923.zip

Link to post
Share on other sites
Brian and Jim,

Thanks. I try these out tomorrow, it's getting late here. Did you try if your solutions work if the class is embedded into a library i.e. the name is something like this: MyLib1.lvlib:MyLib2.lvlib:MyClass3.lvclass?

Yes, the type string contains the full Library path (TestLibrary.lvlib:TestClass.lvclass) so just add ":TestClass.ctl" and Open VI reference works just as before.

Link to post
Share on other sites
Here is a tool that should work (I just whipped it up). It depends on the OpenG oglib_lvdata library. After some testing and clean-up, I'll add it to the oglib_lvdata library.

Cheers,

-Jim

Jim: Test cases would be a simple class, a class owned by another library and the all important LabVIEW Object class. LVObject is actually encoded slightly different to guarantee that even if you clever users try to name a class "LabVIEW Object" that we can still distinugish the real LV Object class. The encoding for most classes is:

name = length | cpstrlist

cpstrlist = [lenghth | text]+

length = a single character (byte)

(where | means "followed by" and + means "repeat one or more times as needed)

The encoding for LabVIEW object is simply

name = length | "LabVIEW Object"

Link to post
Share on other sites
  • 1 month later...
LVObject is actually encoded slightly different to guarantee that even if you clever users try to name a class "LabVIEW Object" that we can still distinugish the real LV Object class. The encoding for most classes is:

name = length | cpstrlist

cpstrlist = [lenghth | text]+

length = a single character (byte)

(where | means "followed by" and + means "repeat one or more times as needed)

The encoding for LabVIEW object is simply

name = length | "LabVIEW Object"

What do bytes 08-11 in type string of a LVClass mean? The bytes get a hex value 0xFFFFFFFF for LabVIEW Object but the value for other labview classes varies. The variation does not depend on the class but something else. Does this somehow refer to the current application instance or has anyone figured out the meaning of these bytes? The indexes above are assumed to start from zero i.e. byte 08 is the 9th byte in the type string.

The first two bytes define the length of the type string in a big-endian form. The bytes 02-07 are always the same for all LabVIEW classes and I assume these refer to LabVIEW classes in general. The type string for these bytes seems to be always 0x4070001E0000.

Link to post
Share on other sites
  • 2 weeks later...
What do bytes 08-11 in type string of a LVClass mean? The bytes get a hex value 0xFFFFFFFF for LabVIEW Object but the value for other labview classes varies. The variation does not depend on the class but something else. Does this somehow refer to the current application instance or has anyone figured out the meaning of these bytes? The indexes above are assumed to start from zero i.e. byte 08 is the 9th byte in the type string.

The first two bytes define the length of the type string in a big-endian form. The bytes 02-07 are always the same for all LabVIEW classes and I assume these refer to LabVIEW classes in general. The type string for these bytes seems to be always 0x4070001E0000.

Looks suspiciously like the 16bit typestring array in older Flatten to String functions. The first word 0x4070 is the actual type with the higher 8 bits being flags such as indicator/control etc, and 0x70 being the typecode for any LabVIEW refnum. Then follows a refnum type word and after that a variant (C union, not LabVIEW variant) construct depending on the refnum type. 0x001E seems to be the refnum type for LabVIEW classes. 0x0008 is for all kind of VI server refnums for instance.

Rolf Kalbermatter

Link to post
Share on other sites
Looks suspiciously like the 16bit typestring array in older Flatten to String functions. The first word 0x4070 is the actual type with the higher 8 bits being flags such as indicator/control etc, and 0x70 being the typecode for any LabVIEW refnum. Then follows a refnum type word and after that a variant (C union, not LabVIEW variant) construct depending on the refnum type. 0x001E seems to be the refnum type for LabVIEW classes. 0x0008 is for all kind of VI server refnums for instance.

Rolf is correct. LVClasses are not refnums, but internally I borrowed some of their syntax and it was easiest to make them a (get this) "by value form of refnum." That's not as much of a hack as it sounds -- refnum is sort of a misnomer at this point, and internally refnums would be better named as "any data type with a hierarchy". I wasn't even the first to use a by-value hierarchy -- credit for that goes to one of the DAQ groups.

Bytes 8 thru 11 are a hex value that indicates which application instance this LV class is loaded in. It will be different every time the class loads into memory (and is ignored when flattening/unflattening to disk). Notice that I could have Alpha.lvclass loaded into one application instance which has as its private data two ints. In another application instance I could have a different Alpha.lvclass that has a string. The name of the class is not enough to distinguish the datatype -- we need to know which context to look at. The FFFFFFFF for LabVIEW Object is a special code for "union of all app instances" -- I only have a single instance of LabVIEW Object class that is used by all app instances. Occassionally you will see values other that FFFFFFFF in a LV Object type descriptor when data from a specific class has been upcast onto an LVClass wire.

There's also 4 bytes for flags. This is pretty much left as room for future expansion of the data type. It's a reflex of mine -- when building something that will be very hard to mutate and where the penalty for bad design could have effects lingering for generations, leave yourself some extra bits to encode mutation. ;-)

Link to post
Share on other sites
  • 2 weeks later...

It seems that the actual runtime type is only in the data string and not in the type string. Type string only tells the type of the wire which may or may not coincide with the actual runtime type. So does anybody know (Aristos) how the runtime type is encoded to the data string? I could try to reverse engineer but it's always a little unsafe as one may make mistakes. All the solutions provided here have been related to the compiletime type and not the runtime type.

Tomi

Link to post
Share on other sites

QUOTE(Tomi Maila @ Feb 15 2007, 11:17 AM)

It seems that the actual runtime type is only in the data string and not in the type string. Type string only tells the type of the wire which may or may not coincide with the actual runtime type. So does anybody know (Aristos) how the runtime type is encoded to the data string? I could try to reverse engineer but it's always a little unsafe as one may make mistakes. All the solutions provided here have been related to the compiletime type and not the runtime type.

When a LVClass is flattened to a string, the first 4 bytes form an unsigned 32-bit integer of "number of levels of hierarchy flattened." So if I have a hierarchy "LV Object->Parent->Child" and I flatten an instance of Child, then this will be a 2. So the first thing to check is if this number is zero then you have an instance of LabVIEW Object in your hands. If you find a zero, there is no further data in the string.

After the numLevels value comes an encoding of the fully qualified name of the class. It follows the same encoding used to encode the name in the int16-array version of the type descriptor.

Link to post
Share on other sites

Thanks AQ :) Still a few more clarifications.

QUOTE(Aristos Queue @ Feb 16 2007, 05:39 PM)

Is there any other way to find out the parent class hierarchy of runtime class in question other than using LV Class Library (private) scripting nodes?

QUOTE(Aristos Queue @ Feb 16 2007, 05:39 PM)

So the first thing to check is if this number is zero then you have an instance of LabVIEW Object in your hands. If you find a zero, there is no further data in the string.

Does LabVIEW object have different name in different LabVIEW language versions. So if I interpret 0 to be LabVIEW Object, do I also have to find out what is the name of the LabVIEW Object in this language version or is LabVIEW Object a universal class name? I only have an English version of LabVIEW so I cannot test this.

Tomi

Link to post
Share on other sites

QUOTE(Tomi Maila @ Feb 16 2007, 11:13 AM)

Those are private functions? Really?

I don't use the G code interface to classes much, but I thought all of the scripting access for classes was wide open public. But, to answer your question, no there's no way to get the hierarchy otherwise. Well, you could by brute force type testing, but that would be ridiculous.

QUOTE(Tomi Maila @ Feb 16 2007, 11:13 AM)

Does LabVIEW object have different name in different LabVIEW language versions. So if I interpret 0 to be LabVIEW Object, do I also have to find out what is the name of the LabVIEW Object in this language version or is LabVIEW Object a universal class name? I only have an English version of LabVIEW so I cannot test this.

You know, I honestly have no idea.

Link to post
Share on other sites

QUOTE(Aristos Queue @ Feb 16 2007, 10:16 PM)

Those are private functions? Really?

I don't use the G code interface to classes much, but I thought all of the scripting access for classes was wide open public. But, to answer your question, no there's no way to get the hierarchy otherwise. Well, you could by brute force type testing, but that would be ridiculous.

All invoke nodes and all property nodes but one of class LVClassLibrary are under scripting license. Perhaps you could talk your boss to open these in the next maintenance release of full release which ever comes first. Especially important would be Parent Class property. Strong are you with the force...

Tomi

Link to post
Share on other sites

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.