Serialize and deserialize objects in VB6
Hello, I've got a bad ass problem again :( - I did try the code from here:
http://www.vb-helper.com/howto_vb6_serialize.html
It works great in the IDE interpreter, but after compilation, it crashes at following line:
Code:
For Each tMem In TLI.InterfaceInfoFromObject(Object).Members
Depending on the project, there is either the message "runtime error 445" - or no error message...
Does anybody have an idea, why this is and how I can fix it? :wave:
I would really appreciate every single hint! :o
Re: Serialize and deserialize objects in VB6
Can you handle the problem with error trapping?
Is this on Vista?
Does this occur when making calls to/from the registry?
Re: Serialize and deserialize objects in VB6
IIRC, the typlibinfo object is not meant to be run in compiled apps,
since typelibs are compiled into the exe. This is why tlb's are not
required to be shipped as part of an installation.
Re: Serialize and deserialize objects in VB6
Hello Hack, thank you for your answer!
Quote:
Originally Posted by
Hack
Can you handle the problem with error trapping?
I guess not. I just tried On Error Resume Next - but this does not change anything.
The mentioned line of code should be pretty fundamental for the serializing process - so there shouldn't be any error at all...
I am developing on XP SP3, but tested it also on 7: same effect there (I did run it as admin)! (on Vista it should be the same like on 7)
Quote:
Does this occur when making calls to/from the registry?
No, there are no registry calls at all.
The code uses Microsoft XML, v2.6 and TypeLib Information components to retrieve all class members. It returns the class properties as XML string, which is stored to disk afterwards (in AppData folder).
Please check the code on the linked page (link on the bottom) to see what I mean.
In IDE everyhing works perfectly, but after compilation it is the opposite:
Reading the XML file does not work, but there also no crashes/errors occuring.
Trying to write the XML file does send my app to nirvana... :(
Re: Serialize and deserialize objects in VB6
Quote:
Originally Posted by
VBClassicRocks
IIRC, the typlibinfo object is not meant to be run in compiled apps, since typelibs are compiled into the exe. This is why tlb's are not required to be shipped as part of an installation.
Ok, this makes sense.- But how can I get the code working as compiled exe?
Re: Serialize and deserialize objects in VB6
Quote:
Originally Posted by
VBClassicRocks
IIRC, the typlibinfo object is not meant to be run in compiled apps,
since typelibs are compiled into the exe. This is why tlb's are not
required to be shipped as part of an installation.
TlbInf32 is a DLL, not a TLB, and can run in a compiled exe. A COM DLL(or OCX) has a type library stored in it. TlbInf32.Dll wraps API oleaut32.LoadTypeLib() which lets you load Com object and returns the ITypeLib interface.
Re: Serialize and deserialize objects in VB6
Thank you for all your hints. :)
Quote:
Originally Posted by
DrUnicode
TlbInf32 is a DLL, not a TLB, and can run in a compiled exe.
That means, there should be a solution for my problem, right?
But how can I get it to work?
1 Attachment(s)
Re: Serialize and deserialize objects in VB6
Without seeing your code it is hard to know what to say. Can you create a small example program that fails in the way you have described?
It seems to work here.
Tiny demo attached.
Re: Serialize and deserialize objects in VB6
Many thanks dilettante, your demo gave me the key!
I did not compile my classes to a dll - if this is done, it works also on my system as executable. :cool:
I guess, I have to move my classes out now... :D
(My example should not be needed any more now.)
But I have got another question now:
Is it possible to serialize arrays and object this way also?
Code:
' If tMem.ReturnType.VarType = VT_DISPATCH Then
' '.. do nothing or do it recursive
' ElseIf tMem.ReturnType.VarType = VT_ARRAY Then
' '.. do nothing or do it somehow else
' End If
I think this comment is pointing out, that this is doable - do you have an idea, how to fulfill this task also?
Re: Serialize and deserialize objects in VB6
The first If there is checking for a Property that is an object I think. So as suggested, you'd need to have the routine call itself recursively to handle THAT object's properties too. This would require more work though, since you'd want the sub-object inserted into the parent object's XML.
The second If is detecting an array of course. This would also require some more work, first deciding how you want an array to be represented in your XML, then writing the code required to create those XML nodes and populate/extract each array element.
While the example Function works, it is pretty ragged and primitive. You should probably rewrite the whole thing as a Class. Instead of one Function you could then have several routines bundled together. I suggest this because you'll probably find you have code you want to reuse, like the code you'll need for handling each property can be reuse when processing an array - which will also need to process objects in the array.
There is another approach that is more in the spirit of VB6 and it doesn't need the TlbInf32.dll either. Plus it should work for internal private Classes as well as public (registered COM DLL) classes:
XML Property Bag
This should be familiar to anyone who has used VB6's native binary PropertyBag objects for persistence.
1 Attachment(s)
Re: Serialize and deserialize objects in VB6
Hello dilettante, thank you for your reply. I guess I need your Help again. :)
Quote:
Originally Posted by
dilettante
The first If there is checking for a Property that is an object I think. So as suggested, you'd need to have the routine call itself recursively to handle THAT object's properties too. This would require more work though, since you'd want the sub-object inserted into the parent object's XML.
The second If is detecting an array of course. This would also require some more work, first deciding how you want an array to be represented in your XML, then writing the code required to create those XML nodes and populate/extract each array element.
Ok, that was acutally pretty clear to me too - but not how to solve this in detail... ;)
I did spend some nights on that topic now and it seems, that I did run into some problems!
I could do this for the object handling - please see the attached project. (btw: objects (class instances) acutally have the VarType VT_VARIANT).
But I have problems with arrays: Since VB does not allow public arrays in classes, one must use Let and Get properties to make private arrays public. Getting the array works also, but how can I Let it back?
There would also be the possibility to use a parameterized property to return the array. But in this case my serializer cannot retrieve the array bounds.
The only thing I can do is, to assume that a property with one parameter is an array. Then trying to use zero as the first parameter. If this fails, trying it with 1 and than looping until an error occurs. But then the class is limited to array indexes starting at 0 or 1.
I would like to implement both features, so that my lib is as much flexible as possible.
Quote:
Originally Posted by
dilettante
While the example Function works, it is pretty ragged and primitive. You should probably rewrite the whole thing as a Class. Instead of one Function you could then have several routines bundled together. I suggest this because you'll probably find you have code you want to reuse, like the code you'll need for handling each property can be reuse when processing an array - which will also need to process objects in the array.
Hmmm. I did split the function into serialize and deserialize for better readable code. For having objects as properties or objects in array properties, I can call my functions recursively. Why do I need a class for this?
Quote:
Originally Posted by
dilettante
There is another approach that is more in the spirit of VB6 and it doesn't need the TlbInf32.dll either. Plus it should work for internal private Classes as well as public (registered COM DLL) classes:
XML Property Bag
This should be familiar to anyone who has used VB6's native binary PropertyBag objects for persistence.
Yes, I did use PropertyBag objects for UserControls, but I don't like them actually, because they need a lot of extra code... :rolleyes:
The reason for my serializer was to save an applications settings configuration. I thought, the best would be to instantiate a class, which holds all the parameters and saving that object to disk. Doing this binary would cause problems, if parameters are added in newer versions of the application. - At least users will lose their configuration in this case.
So I came up with the idea to serialize the object. The intension is to have an universal serializer, which can handle any kind of class WITHOUT writing extra code within the class (this is also the reason, why private properties are not an issue - there are no private properties in my case).
The property bag solution needs this and it would blow up the code by 200% (every property/parameter needs code for reading and writing). Instead of doing this, I could also write an ini file via an extra module and keep the classes itself clean.
By the way: When was this XMLPropertyBag solution implemented by Micorsoft? I am asking, because I found a pretty similar solution here:
http://www.xml.com/pub/a/1999/09/ser...on/index3.html
http://www.planet-source-code.com/vb...52397&lngWId=1
I am wondering, why they do this in that way???
Why having an event for reading AND writing seperatly? - Wouldn't it half the work, if that is done just in one routine?
I did change the code that way and it works perfectly (please see the other folder in the attachment)
Re: Serialize and deserialize objects in VB6
As far as I know Microsoft never made an XML PropertyBag for VB6. All of them I've seen have been put together by users.
It sounds like you have a solution now though.