Jump to content

"Get LV Class Default Value" from memory, not from disk


Recommended Posts

I need to get an instance of a class that I know will be loaded with my application, but "Get LV Class Default Value" seems only to work with a full on-disk path to the .lvclass file. I tried passing in a string with the fully qualified name of the class, but it gives me error 7. Is there a way to get an instance of the class on my block diagram by referencing it in memory?

post-17939-0-39197200-1341260909_thumb.p

(This is for a generic object deserializer, so I can't simply drop a constant of the class on the block diagram.)

(No, I'm not trying to reproduce AQ's work in the other thread on serialization. Although the VI I'm writing is generic, the serializer is mostly special-purpose.)

Edited by Stobber
  • Like 1
Link to comment

I've run up against this too. What I wouldn't give for a more complete implementation of LabVIEW Object.

There's only one way around this as far as I know: build your own look-up table.

If your aware of all of the possible object types this is easy, you just need to translate an identifier to a value. If you don't have control over all the serialized types prior to distribution, you're likely going to have to roll a far more involved solution where you can register a type with a given identifier, provide a mechanism for dynamic type registration, and a factory method that spits out values for a given identifier.

I keep using the generic term identifier instead of qualified name because even though a qualified name is one of the most fundamental properties of a class, we don't even have access to that, save for some hacks that are performance killers.

AQ, maybe I misunderstood the question, but I think Stober needs a means of translating a qname to a value, which isn't covered in that post? Those VIs only work if you already have a value (or path)...

Link to comment

AQ, maybe I misunderstood the question, but I think Stober needs a means of translating a qname to a value, which isn't covered in that post? Those VIs only work if you already have a value (or path)...

mje understood the question correctly. I'm storing the qualified name of the class in the string, and I want to use it to create a new object of that type when I deserialize. I looked at those Open_G VIs before posting. Maybe neither of us understands how to use them to solve this problem?

Link to comment

Yeah... I misunderstood. And I've run into the same problem. I've already been working on LV 2013 to add these functions. In the meantime, I gave Staab a workaround. If it works for him, I'll let him repost it here.

(an unfortunate but workable workaround for limited use cases).

  • Like 1
Link to comment

AQ's workaround for a deployed application (always my situation) is to add the .lvclass files to specific paths inside the built EXE, then provide a path to the class file using the Application Path primitive and a relative path inside the EXE. It doesn't actually pull an instance of the object from the application's memory space using the qualified name, but it's a workable approach since the EXE path can be obtained using a prim.

To specify the location of the .lvclass file inside the EXE, add it to the "Always Included" list in the build spec, then create a "Destination" for it with the full path. For XYZ.lvclass, an example Destination Path would be C:\build\MyApp.exe\XYZ\. When you want to load an object of XYZ at run time, you provide the path C:\build\MyApp.exe\XYZ\XYZ.lvclass

AQ told me that all the classes to be loaded need to be either inside the EXE or outside it; they can't be mixed. I didn't test that assertion b/c all my classes will be shipped in the built EXE.

  • Like 1
Link to comment

Staab: I thought of a second solution for you... you could build a Variant attribute database where the key is the name of the class and the value is the default value of the object. That does away with requirements to put the classes in a particular location in the EXE.

mje: If the class is already in memory, there's no need to go back to disk on subsequent calls. The rules are the same as opening a VI reference for a VI already in memory.

Link to comment

Staab: I thought of a second solution for you... you could build a Variant attribute database where the key is the name of the class and the value is the default value of the object. That does away with requirements to put the classes in a particular location in the EXE.

That's what mje was talking about with the "lookup table".

Link to comment
  • 4 weeks later...

AQ's workaround for a deployed application (always my situation) is to add the .lvclass files to specific paths inside the built EXE, then provide a path to the class file using the Application Path primitive and a relative path inside the EXE. It doesn't actually pull an instance of the object from the application's memory space using the qualified name, but it's a workable approach since the EXE path can be obtained using a prim.

To specify the location of the .lvclass file inside the EXE, add it to the "Always Included" list in the build spec, then create a "Destination" for it with the full path. For XYZ.lvclass, an example Destination Path would be C:\build\MyApp.exe\XYZ\. When you want to load an object of XYZ at run time, you provide the path C:\build\MyApp.exe\XYZ\XYZ.lvclass

Is there any reason this method would not work in a Shared Lib DLL? I've built a test project with build specs for both an EXE output and a DLL. Both use the method described above, using the appropriate name (...\MyApp.exe\XYZ\ or ...\MyApp.dll\XYZ\) for the Destination Path. The EXE loads the class fine, but the DLL still gives Error 7 on the "Get LV Class Default Value" call. Anyone have ideas/thoughts on this one? Has anyone successfully loaded a class dynamically in a Shared Lib (from memory, not from disk)?

Link to comment
  • 7 months later...
  • 5 weeks later...
  • 9 months later...
  • 3 months later...

OK I found NI's "Class retrieval" library that does the job, in the NI Tools Network, but the minimum requirement is LV 2012, though I'd need it for 2011 :(

 

It could have been a matter of saving the library to LV2011, but there are password protected VIs like "2013 Get LV Class Default Value By Name.vi". This VI is precisely aimed at using builtin 2013 functionality when run from LV2013. For now I've came up with removing this code that uses 2013's bultin VI, and always use the pre-2013 workaround.

 

FWIW I need it for implementing class instance deserialization in the JSON API.

Link to comment
What's the path to the Class Retrieval library? I'd like to poke around and see what it can do!

It's in <vi.lib>/NI/Class Retrieval/.

 

Basically it is built around a FGV that holds a lookup table between class names and paths, and when ran from LV2013 it delegates this to the native VIs (that are password protected, since built into LabVIEW).

 

For pre-2013, if the class isn't found in the table, it asks uses LabVIEW's project introspection to find it, so your classes just have to live in the project. When ran from an executable, you have to preload your classes to fill the lookup table (there's a VI for that too).

Edited by CharlesB
Link to comment

CharlesB: You'll find that the class retrieval has a really nasty performance curve. There really isn't a good solution until 2013... I tried hard to find one, but hit too many performance issues with every other approach, and finally cut a new interface into LV.

 

(To be clear... it does work... and if you don't have a tight loop, it works fine. It's the performance that was the issue.)

Edited by Aristos Queue
Link to comment
To specify the location of the .lvclass file inside the EXE, add it to the "Always Included" list in the build spec, then create a "Destination" for it with the full path. For XYZ.lvclass, an example Destination Path would be C:buildMyApp.exeXYZ. When you want to load an object of XYZ at run time, you provide the path C:buildMyApp.exeXYZXYZ.lvclass

 

I'm running into a really weird issue with this workaround. I created many destinations like this and it seems to work as desired: the files get built into the exe. However, now the Installer fails to build correctly. The Installer seems to think that "MyApp.exe" is an actual system folder. It looks for my lvclasses in this nonexistent system folder and returns an error when it can't find them.

 

Has anyone run into this before? Is there something wrong with the way I defined my destinations?

 

spPZX1v.png

 

EDIT: I know that the "Yen" symbol is showing up instead of backslash; that's some weird artifact of my virtual machine that I haven't sorted out. But rest assured the same issue manifests itself on normal desktops that display the backslash as normal.

Edited by Mike Le
Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
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.