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:
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