Fast serialization for third party object

R

ronnotel

I have integrated APIs from a third party into my framework. The third
party is essentially a .Net wrapper on top of an existing set of C++
classes and structs.

I want to pass-around objects in these native structures as much as
possible - that is I don't want to fool around with object
serialization/deserialization. Data rates approach several hundred
thousand objects per second, hence I simply can't pay the performance
penalty this would entail. All of the structures are fixed-size
formats, so simply copying byte-arrays from structure to structure is
my preferred approach.

Unfortunately, the third party neglected to mark one important class as
serializable so I have followed the 'Manual Base Class Serialization'
pattern set down in the Advanced Serialization article:

http://msdn.microsoft.com/msdnmag/issues/04/10/AdvancedSerialization/

For instance:

public class ThirdPartyClass()
{
}

[Serializable]
public class MySerializableClass() : ThirdPartyClass
{
public void GetObjectData(SerializationInfo info, StreamingContext
context)
{
SerializationUtil.SerializeBaseType(this, info, context); // (see
article for details)
}
}

However, because C# has no built in mechanism to coerce a downcast, it
seems I need to manually force the coersion. That is:

ThirdPartyClass thirdPartyObj = ThirdPartyAPI.GetObject();
MySerializableClass myObj = (MySerializableClass)thirdPartyObj; <<<
THROWS InvalidCastException

throws an exception at the attempted downcast.

I have worked out a brute force technique to force the downcast by
marshaling the object into an unmanaged array of bytes and back again,
ala:

[Serializable]
[StructLayout(LayoutKind.Sequential)]
public MySerializableClass
{
public static MySerializableClass CloneFrom(ThirdPartyClass
thirdPartyObj)
{
IntPtr ptrOut = Marshal.AllocHGlobal(Marshal.SizeOf(thirdPartyObj));
Marshal.StructureToPtr(thirdPartyObj, ptrOut, true);
MySerializableClass wrapper = new MySerializableClass();
Marshal.PtrToStructure(ptrOut, wrapper);
Marshal.FreeHGlobal(ptrOut);
return wrapper;
}
}

Thus, a quick call to this method returns a serializable object that
can be passed around between processes:

MySerializableClass myObj =
MySerializableClass.CloneFrom(thirdPartyObj);
aRemotable.SomeMethod(myObj);

QUESTION: Is this the correct technique for what I'm trying to do?
Also, I'm confused why the I need to include the attribute
[StructLayout(LayoutKind.Sequential)] for this to work.

All feedback is appreciated (yes, I know this is not the 'approved'
..Net way of handling things).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top