Jump to content

Unflatten LabVIEW class works until built in application


Recommended Posts

I have a class hierarchy something like top-level-class, which has no children, but contains an array of worker-class objects. There are about ten specific types of worker-class, all children of parent-class. The array usually only has a few types in it at any given time.

Now I want to save top-level-class to a file. I have tried flattening to xml and saving as well as just using the write binary primitive. In both cases I get the same result. Everything is fine and dandy in the Dev

environment, but fails in the build application when I try to read the file from disk. I get:

Error 1403 occurred at Read from Binary File

LabVIEW: Attempted to read flattened data of a LabVIEW class. The data is corrupt. LabVIEW could not interpret the data as any valid flattened LabVIEW class.

In my build spec, I have everything in the project (except top-level.vi) in Always Included (under Source Files). top-level.vi is the startup file.

I am at a bit of a loss how to proceed. Has anyone encountered this or have an idea where I might have gone wrong?

George

Link to comment

That is a good question. No, I don't think they are. The specific worker-class children don't have any constants or controls/indicators anywhere in the application. The files are generated by a different application (but part of the same project). What is a good way to load them all into memory before reading the file?

Link to comment

I just put a constant down and wire it to the get default path primative. Its helpful to see where its being loaded from to make sure its using the ones compiled into the application.

I've actually been messing around with this technique a little bit; I'm not sure its a great idea to be compiling 2 disk copies. It would be better to have a packed library with the child classes (although this introduces a whole new set of issues in maintenance and understand-ability) There really should only be one copy of the compiled code in the run time environment at a time.

Link to comment

I do the loading of a class from one of the methods, basically I 'construct' the class from file. So I have e.g. a Load method for constructing a class+data from a file and a New method for constructing it without data (or whatever the New method needs to do to initialize the data, which in my case is nothing). Since the class' load method is called, it will for sure be present in the exe, as well as the classes it aggregates (Channel in my case). Works fine here.

post-906-0-08810900-1327964765_thumb.png

Link to comment

You wont get 1403 from a class not in memory problem. 1403 only occurs when you flatten an object of class XYZ to a string, then try to unflatten that string using a completely unrelated XYZ class -- like flattening an XYZ that contains an integer and then unflattening with an XYZ that contains a string, and not a different version of the class, but one where we try to interpret that integer as the length bytes of the string and realize we don't have enough bytes in the flattened string to represent a string of that size.

I don't know exactly what you're doing, but my first bet would be cross-linking of some sort. In other words, the class that you're using during development is *not* the same class that you're loading in your built application.

Link to comment

This works in the development environment, but fails with error 1403 after it is build into an application. Add class constants for WorkerA and WorkerB to the diagram of "UseFile" and the application will run without errors. So it does seem to be a class not in memory problem, but putting constants on the actual block diagram is not a solution I like, since there are lots of worker classes, and I will add new ones regularly.

post-17850-0-49289800-1328020215_thumb.p

Link to comment

Well, I am pretty sure it is a simple class not in memory problem. Pity LabVIEW didn't offer that in the error message in the first place. Anyway, getting the classes loaded seemed trickier than I thought it would be. So maybe there is a better way? My solution was to add a pre-build action to store the relative paths to the worker classes. Then the application can use that information to dynamically load all of the worker classes before it does anything else.

Pre-Build Action:

post-17850-0-03911600-1328034153_thumb.p

Changes to top level vi:

post-17850-0-69376700-1328034172_thumb.p

  • Like 1
Link to comment
  • 1 year later...
  • 1 year later...

Just bringing this thread back from the past.  I ran into this exact same issue in LV2015.  Here are some details:

Sending a message from app1 to app2.

Message payload is a class with some data members also being objects (composition).

Everything was working fine in IDE and EXE.

Changed one of the data members from a 2D array to an array of objects with the following structure:

Parent class with abstract methods.  Two child classes with concrete methods.  Two grandchildren classes with different private data than one of the child classes.  (the grandchildren only inherit from one of the children to specify some finer details for that branch in the tree).

post-2411-0-87291500-1444680717.jpg

sending message from app1 to app2 in the IDE continues to work fine.

Build both EXEs and suddenly error 1403 rears it's ugly head.

After much work trying to get to the bottom of this, I find this post.

I place a static copy of the child and grandchild classes on the BD of the top level VI in the app2 EXE.

Problem solved!

 

Oh, and I never called any flatten functions when sending my message.  Instead I am calling a VI in app2 from app1 using call by reference node.  (This VI puts the message object in the receiver's queue.)

 

So, apparently, the call by reference node uses the flatten/unflatten object function under the hood.  And also, that function has no problem resolving the class type in the IDE but fails in an EXE.

I have ensured that app2 has all the classes in it's project and they are even marked 'always include' in the app builder.  So, they are in the EXE but maybe not in memory already.  Still, it should be able to find them and unflatten the data without the static links I had to add.  And in any case, this error message is extremely misleading because there is no corruption happening.  The RTE just cannot find the class definition.

 

I hope that a CAR can be created to finally address this situation.  And I hope future versions of LabVIEW can do a better job of reporting the correct error.  Even better would be a version of LabVIEW where code ran the same way in an EXE as it does in the IDE.

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
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.