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/is...Serialization/
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).