LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Unflattening LVOOP class from string in executable does not work

Hi everybody

Situation: I need to send an LVOOP class through a network streaming queue. Since this type of queue does not support the transfer of LVOOP classes (also not as variants), I first flatten my class to string and then send the result through the queue:

 

send_class.png

 

 

 

On the receiving side, I unflatten from string and then convert the variant back to the class:

unflatten from string and convert to LVOOP class

 

Problem: I need to run the receiving VI as a built executable (EXE) in order to be able to set its Windows process priority independent of the sender. Sending and receiving of the LVOOP class works perfectly fine if both sender and receiver are run as unbuilt VIs directly from the LV project browser (i.e., in the "development mode"). However, when the receiver is running as an executable, I get confronted with error 1403 ("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.").

 

Can anybody give me a hint on how I could solve this problem?

 

Message 1 of 14
(4,599 Views)
I don't know what would cause that. But have you tried flatten to xml?
=====================
LabVIEW 2012


Message 2 of 14
(4,586 Views)

Thanks for this advice. Unfortunately, the unflattening from XML yields the same error 1403...

0 Kudos
Message 3 of 14
(4,578 Views)

My suspicion is that the class that has been packed into the exe file is considered somehow different from the one in the sender.vi (although it should be the same).

0 Kudos
Message 4 of 14
(4,576 Views)

If you can access the raw data from on the receiver, it might be worth checking the full class name and/or version of the class being unflattened. For example, classes wrapped in libraries are "different" to the same class not wrapped in a library (the full name of the class changes). Also, if the EXE has an older version of the class than is received, it also will not be able to unflatten it. 

0 Kudos
Message 5 of 14
(4,567 Views)

Other than moving the class into another library (or packed library), renaming the class also causes its mutation history to be reset. Basically, this causes LV to think the class is another class.


___________________
Try to take over the world!
0 Kudos
Message 6 of 14
(4,561 Views)

@shew82 and tst: thank you for your inputs.

 

I have been continuing experimenting in the meantime. As it seems, neither name nor version history of the class to be sent (let's call it ClassA) are at the root of the problem. Rather, it seems to have to do with a dynamically loaded attribute in the private data of ClassA. In more detail:

  • in the private data of ClassA, there is a member variable variableX that is of type ClassB.
  • in the method ClassA:initialise.vi, a configuration file is read, in which the path of a ClassC is specified. ClassC, which inherits from ClassB, is then instanced dynamically and assigned to variableX.

How did I come to the conclusion presented above?

  • ClassA can be sent and unflattened perfectly fine if in the configuration file, I specify ClassB to be instanced and assigned to variableX (in that case, the actual value of variableX is of the very same type as variableX and is not a child class thereof).
  • I realised that the executable of course needs to have access to ClassC in order to load it dynamically at run-time, but that at built-time, LV doesn't know about this. Therefore, I added ClassC to the list of always included source files in the build specification of my executable. However, although the executable should now have access to the class to be instanced dynamically, the original error still shows up.

Basically, the error seems to occur because the member variable does dynamically hold a value that is of a different type than the one declared for the member variable in the class definition.

 

Does this behaviour make any rational sense or do we have to attribute it to an underlying bug in LabVIEW itself?

0 Kudos
Message 7 of 14
(4,548 Views)

I just got further evidence for the claim in my previous post above: I modified variableX in the private data of ClassA now to be of type ClassC and removed the dynamical class loading from ClassA:initialise.vi.

 

Now, with static loading, both the type of the actual value and the defined type of variableX are ClassC. Under these circumstances, transfer and unflattening of ClassA work properly. However, this modification is not something I can live with because I need the flexibility of dynamic class loading based on configuration file content.

 

 

0 Kudos
Message 8 of 14
(4,541 Views)

@dlanger wrote:
Therefore, I added ClassC to the list of always included source files in the build specification of my executable. However, although the executable should now have access to the class to be instanced dynamically, the original error still shows up.

Make sure that you know where classC is. Just adding it to the build doesn't mean it ends up where you expect it be to when you dynamically load it. Of course, if it isn't there, you should get an error when you attempt to load it, but maybe you're not checking for that?

 

Overall, we play better when we have actual code to deal with.


___________________
Try to take over the world!
0 Kudos
Message 9 of 14
(4,537 Views)

@tst: Loading is done on the receiver's side, i.e., never in a built executable. So that shouldn't be the problem.

 

Since I cannot post my whole application, I quickly replicated the problem in a example project (LV2010). See attachment...

 

  • when receiver and sender are run as VIs, sending of the classes works nicely, for both ClassB and ClassC.
  • when the receiver is run as executable (build "receiver without packed ClassC"), only ClassA can only be sent with an object of ClassB as an attribute, but not with ClassC.
  • when the receiver is run as executable including a packed ClassC (build "receiver with included ClassC"), sending also does only work for a ClassB-type attribute (i.e,. same as above).
0 Kudos
Message 10 of 14
(4,527 Views)