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
Unflatten LabVIEW class works until built in application
Started by
GeorgeG
, Jan 30 2012 10:18 PM
8 replies to this topic
#1
Posted 30 January 2012 - 10:18 PM
#2
Posted 30 January 2012 - 10:24 PM
Are all the classes loaded into memory before you read the file?
Certified LabVIEW Architect
#3
Posted 30 January 2012 - 10:28 PM
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?
#4
Posted 30 January 2012 - 11:06 PM
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.
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.
Certified LabVIEW Architect
#5
Posted 30 January 2012 - 11:08 PM
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.
#6
Posted 30 January 2012 - 11:21 PM
#7
Posted 31 January 2012 - 05:00 AM
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.
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.
#8
Posted 31 January 2012 - 02:30 PM
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.
#9
Posted 31 January 2012 - 06:29 PM
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:
Changes to top level vi:
Pre-Build Action:
Changes to top level vi:











