G#

cancel
Showing results for 
Search instead for 
Did you mean: 

Serialization

Hello there;

i have a question, what if i want to serialize an object which has other objects in its object attributes. as far as i can see when you serialize the root object it only writes the objects information but not the attributes of the object contained in the atributes of root object. What do you suggest to over come this problem? Thank you in advance.

0 Kudos
Message 1 of 3
(6,202 Views)

Hi,

If I understand you correctly, you have a class and in this class you aggregate other classes by keeping references to these in your object attributes. In other words, a standard aggregates of objects. If you serialize an object that has other objects aggregated, these will be serialized as well recursively. This is very common if you have a tree structured representation of data in you attributes.

When you use serialization and deserialization, notive that there is a boolean input called "Include aggregates?". Set this to true and you entire object graph will be serialized, starting with the top object and all aggregated objects will be serialized recursively.

GObject_Serializec.jpg

When you deserialze your objects back, you must also make sure that "include aggregates" are set to true and all your objects will be deserialized back to the serialization state.

GObject_Deserializec.jpg

When deserializing you have two option regarding the creation of objects.

1) You provide a valid object reference to the "reference in" of the G#Deserialization VI, then the specified object state will be updated.

2) You provide a invalid object reference of the same type (i.e. just place a LV Class constant of the class), then G# Deserializtion will notice that the reference is not valid and just create an object for you.

Since this is a recursive call, you can provide a mix of the above options. I made an example where I have three classes, one class "TestClass.lvclass" that aggregates objects from "MyAggregated.lvclass". Then I have a class called "MySubTestClass.lvclass" which inherits the TestClass.lvclass. This way my example tests both aggregation and inheritance at the same time.

Serialization.jpg

However, I did some testing of this and actually found out that it doesn't work as expected. My serialization of aggregates isn't working for this complex situation, so therefore I have rewritten G#Serialization and G#Deserialization VIs. I also removed XML support for aggregated objects, this is really difficult to implement, so for now, only binary serialization is supported for aggregation of object.

I made a new built G# 1.3.5 (notice that the G# IDE has a different version, same as G# Framework) that I will include in the next release of G# Framework, but I attach it here and you could manually replace the folder <LabVIEW>/vi.lib/addons/_AddQ/G#Object.

When you run this example, an object will be created which aggregates three other objects. Then this object is serialized to file recursively and the objects destroyed. Then you have an option, either you create an new object and deserialized this or you just put in a LabVIEW class constant (for type only) and the lets the serialization VI create the needed objects from the serialization string.

Please let med know if you have any further questions or if I misunderstood your problem.

Regards,

Mattias

Message was edited by: MattiasEricsson  I accidently posted this before I was finished...

0 Kudos
Message 2 of 3
(4,157 Views)

Hi again,

Forget to mension one thing. Please notice that the example above will generate an error 1556, invalid references, if you try to do a binary serialization of an object that has other references aggregated and not includes the aggregates. Why? If you do a complete serialization of an object attributes, the entire object attribute cluster will be serialized including the reference value of the aggregate objects pointer, when deserializing all values in the object attributes cluster wil be replaced from the serialization stream, including the "old", now invalid pointer values (these are assumed killed e.g. if the appication has been closed after it has been serialized). Conclusion is that it doesn't make much sense serializing an object with aggregates and not to include the aggregates (default is to include). It might make sense if the aggregates are created after the serialization again.

However, there is an option if you use XML instead. XML doesn't support aggregate objects serialization, but it does support one other thing, XML Serialization Ignore list. If you implement G#Object_XMLSerializeIgnore.vi in the class to be serialized and provide a string array output with a list of object attributes not to be serialized, you could actually use this feature to serialize an object that has aggregate, but avoid the references to be serialized. Just use XML serialization and put the reference attributes name on the XML ignore list.

When to use XML and when to used binary serialization?

Binary serialization - good for serialization complex data structures

+fast

+supports aggregated object

+small files

-data structure of the object attributes must be identical, else there will be a serialization error

XML serialization - good for serialization of a state where the serialization file could be considered as a configuration file, easy to change, robust against changes in attribute structure.

+human readable files, could be edited in text editor

+robust, new attributes could be added without breaking serialization files (if a new attribute isn't found, the attribute simply will not be written,old value will be used).

+attributes can be ignored by implementing the XML Serialization Ignore List

-no support for aggregated objects

-not as fast as binary

Just some thoughts!

Mattias

By the way, I release the G# Framework 1.4.1 including G# 1.3.5 with the fix for serialization. This is the ONLY difference from the 1.4.0 release a week ago.

0 Kudos
Message 3 of 3
(4,157 Views)