Welcome guest. Before posting on our computer help forum, you must register. Click here it's easy and free.

Author Topic: List<object> to byte array in C#  (Read 39967 times)

0 Members and 1 Guest are viewing this topic.

dbran

    Topic Starter


    Rookie
    • Experience: Experienced
    • OS: Windows 7
    List<object> to byte array in C#
    « on: March 12, 2012, 12:32:58 PM »
    If I have the following code:

    Code: [Select]
    List<object> objList = new List<object>();
    objList.Add(object1);
    objList.Add(object2);

    and object2 is not can not be serialized, how can I get this into a byte array?

    You can not use:

    Code: [Select]
    BinaryFormatter formatter = new BinaryFormatter();
    MemoryStream memStream = new MemoryStream();

    formatter.Serialize(memStream, objList);

    byte[] listBytes = memStream.ToArray();


    because of object2 and:

    Code: [Select]
    byte[] byteArray = (byte[])objList.ToArray();
    will not get it either.  Any other simple possibilities?

    Thanks.

    BC_Programmer


      Mastermind
    • Typing is no substitute for thinking.
    • Thanked: 1140
      • Yes
      • Yes
      • BC-Programming.com
    • Certifications: List
    • Computer: Specs
    • Experience: Beginner
    • OS: Windows 11
    Re: List<object> to byte array in C#
    « Reply #1 on: March 12, 2012, 12:38:01 PM »
    and object2 is not can not be serialized, how can I get this into a byte array?
    You can't. There is nothing to put in a byte array. What do you expect to be written for the nonserializable object?

    an Object that isn't serializable has no persistent representation by definition.
    I was trying to dereference Null Pointers before it was cool.

    dbran

      Topic Starter


      Rookie
      • Experience: Experienced
      • OS: Windows 7
      Re: List<object> to byte array in C#
      « Reply #2 on: March 12, 2012, 12:51:18 PM »
      OK.  I kinda figured.  What I am really trying to do is replace some old VB6 code that looks something like this:

      Code: [Select]
      Dim propBag As PropertyBag
      Set propBag = New PropertyBag

      propBag.WriteProperty "MyObject1", object1
      propBag.WriteProperty "MyObject2", object2

      Dim byteArray() As Byte
      byteArray = propBag.Contents

      The problem with my previous code snippet falls with object2.
      So can you think of a way to do something like this? 

      BC_Programmer


        Mastermind
      • Typing is no substitute for thinking.
      • Thanked: 1140
        • Yes
        • Yes
        • BC-Programming.com
      • Certifications: List
      • Computer: Specs
      • Experience: Beginner
      • OS: Windows 11
      Re: List<object> to byte array in C#
      « Reply #3 on: March 12, 2012, 01:30:01 PM »
      What is "object2" in the VB6 code? Or, more precisely, what type of object is object2?

      if that works with the VB6 code, than whatever object2 is (in VB6) is  Persistable/Serializable.
      I was trying to dereference Null Pointers before it was cool.

      dbran

        Topic Starter


        Rookie
        • Experience: Experienced
        • OS: Windows 7
        Re: List<object> to byte array in C#
        « Reply #4 on: March 12, 2012, 02:03:41 PM »
        object2 is a C++ class that represents a geographical object and is accessed through an interface.  But since it was used in VB6 like it was, I didn't think there would be an issue with serializing it.

        I just attempted a serializable class and passed the two objects in through its constructor and the results were the same.  This doesn't seem like there should be much to it but I am stumped right now.

        I appreciate your input.  Keep it coming...   ;)

        BC_Programmer


          Mastermind
        • Typing is no substitute for thinking.
        • Thanked: 1140
          • Yes
          • Yes
          • BC-Programming.com
        • Certifications: List
        • Computer: Specs
        • Experience: Beginner
        • OS: Windows 11
        Re: List<object> to byte array in C#
        « Reply #5 on: March 12, 2012, 09:13:55 PM »
        Well, that helps...

        That means the Object in question is a COM object (that's the only way a VB6 consumer could access a C++ object); which also answers the question of how it works. a COM Object implements persistence by implementing the IPersist,IPersistStream, and/or IPersistFile interfaces.

        Visual Basic's PropertyBag is smart enough to see when the object you pass it implements one of those interfaces and handles it appropriately; that is, it goes, oh, hey, this object is persistable! And writes the bytes to it's bag.

        However, the .NET SerializationInfo class (the propertybag equivalent) is a managed class and has no understanding of COM; in a similar way to the propertybag, it looks at the object, but it doesn't understand IPersistStream, IPersistFile, etc. It only understands ISerializable and the Serializable attribute.

        I tried to create a test, but it bloated very quickly. I'm not 100% sure how you access the IPersistStream interface and there are about a dozen examples on the web, all implemented in different ways. I ended up with a C# project that had a definition for IPersist, IPersistStream, A wrapper around a COM stream, but no way to create a IStream (ideally, a memory stream...) so I got stuck.

        Basically, it would boil down to this:

        1.Determine if the object supports IPersistStream
        2. if so, create an IStream, and call the objects Save() routine to write it to the stream.
        3. retrieve the bytes from the IStream.

        2. and 3. are a bit of a hairy bit because much like the IPersistStream there is varying information on it. I did find that IStream is present in System.Runtime.InteropServices.ComTypes, at least, but I have no idea how you could <create> such a stream. It's possible to create a wrapper that exposes an existing IStream object, but what you really need is a way to create one, and I wasn't able to find a way to do that.


        I can however, think of a cheap workaround. Instead of trying to implement all this in C# where COM stuff is foreign, you could create a small Wrapper in VB that exposes a method for converting a COM object ot a sequence of bytes by way of the method you illustrated. The only down-side is that you would be forced to compile to 32-bit, but if you are using an Object from a C++ COM DLL already, you are already restricted to 32-bit, so that shouldn't be an issue. Basically, it could be a simple ActiveX DLL that has a single class with a method like this:



        Code: [Select]
        Public Function ComObjectToBytes(Object serializeme) As Byte()
            Dim PropBag As PropertyBag
            Set PropBag = new PropertyBag
            PropBag.WriteProperty("Object",serializeme)
            ComObjectToBytes = PropBag.Contents

        End Function
        Public Function ComObjectFromBytes(Byte readfrom()) As Object
            Dim PropBag As PropertyBag
            Set PropBag = New PropertyBag
            PropBag.Contents = readfrom
            Set ComObjectFromBytes = PropBag.ReadProperty("Object")
        End Function

        You can reference the compiled DLL in Visual Studio, which will create a Wrapper .NET Assembly for you. At that point, you can create the class defined above (whatever it may be called) and call the ComObjectToBytes() method to convert your object2 to a sequence of bytes, which you can then write to your stream. If you want to turn that array of bytes back again, you call the second method in the COM component.

        [/code]

        The COM Interop available with C# is pretty good, but it's also very finicky. Then again, that's COM for you, really :P
        I was trying to dereference Null Pointers before it was cool.

        dbran

          Topic Starter


          Rookie
          • Experience: Experienced
          • OS: Windows 7
          Re: List<object> to byte array in C#
          « Reply #6 on: March 12, 2012, 10:47:05 PM »
          Wow.  Thanks a bunch for sitting down with that!  I am going to look at it again in the morning with fresh eyeballs when I am back in my office.  I follow everything your saying.  I have done a lot of stuff dealing with COM and Interops but never had to deal with serialization before.  I will let the forum know what comes from this tomorrow...

          Thanks again!

          dbran

            Topic Starter


            Rookie
            • Experience: Experienced
            • OS: Windows 7
            Re: List<object> to byte array in C#
            « Reply #7 on: March 13, 2012, 10:16:10 AM »
            OK, so I will throw this out there real quick...

            I have built the class and added it to my project.  The interop gets built as expected.  Here's the catch.  The calling program is installed to the GAC.  When I get to the class creation in the code, the application will fail saying that the file (the new interop for the VB6 code) can not be found.  I have seen this with a couple of other interops in my project.  When the interops are created, they are created as strong named and sharing the same key as the calling application.  With the others, I simply added them to the GAC and they worked as expected.

            With this one, however, the installation to the GAC says that it failed because it was expecting an assembly manifest.  I need a quick fix for this one as well.  Anyone have any ideas?